145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Flat-format binary object format 345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Copyright (C) 2002-2007 Peter Johnson 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#ifdef HAVE_UNISTD_H 3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <unistd.h> 3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <libyasm.h> 3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define REGULAR_OUTBUF_SIZE 1024 3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct bin_section_data { 3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int bss; /* aka nobits */ 3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* User-provided alignment */ 4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *align, *valign; 4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* User-provided starts */ 4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ /*@owned@*/ yasm_expr *start, *vstart; 4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* User-provided follows */ 4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ /*@owned@*/ char *follows, *vfollows; 4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Calculated (final) starts, used only during output() */ 5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ /*@owned@*/ yasm_intnum *istart, *ivstart; 5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Calculated (final) length, used only during output() */ 5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ /*@owned@*/ yasm_intnum *length; 5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} bin_section_data; 5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct yasm_objfmt_bin { 5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_base objfmt; /* base structure */ 5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org enum { 6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NO_MAP = 0, 6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MAP_NONE = 0x01, 6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MAP_BRIEF = 0x02, 6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MAP_SECTIONS = 0x04, 6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MAP_SYMBOLS = 0x08 6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } map_flags; 6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ /*@only@*/ char *map_filename; 6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ /*@only@*/ yasm_expr *org; 6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} yasm_objfmt_bin; 7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* symrec data is used only for the special symbols section<sectname>.start, 7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * section<sectname>.vstart, and section<sectname>.length 7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct bin_symrec_data { 7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section *section; /* referenced section */ 7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org enum bin_ssym { 7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SSYM_START, 7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SSYM_VSTART, 7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SSYM_LENGTH 8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } which; 8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} bin_symrec_data; 8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void bin_section_data_destroy(/*@only@*/ void *d); 8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void bin_section_data_print(void *data, FILE *f, int indent_level); 8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const yasm_assoc_data_callback bin_section_data_cb = { 8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_section_data_destroy, 8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_section_data_print 8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void bin_symrec_data_destroy(/*@only@*/ void *d); 9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void bin_symrec_data_print(void *data, FILE *f, int indent_level); 9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const yasm_assoc_data_callback bin_symrec_data_cb = { 9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_symrec_data_destroy, 9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_symrec_data_print 9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_objfmt_module yasm_bin_LTX_objfmt; 10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_objfmt * 10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_objfmt_create(yasm_object *object) 10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_bin *objfmt_bin = yasm_xmalloc(sizeof(yasm_objfmt_bin)); 10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_bin->objfmt.module = &yasm_bin_LTX_objfmt; 10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_bin->map_flags = NO_MAP; 10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_bin->map_filename = NULL; 11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_bin->org = NULL; 11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return (yasm_objfmt *)objfmt_bin; 11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 115a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.orgtypedef TAILQ_HEAD(bin_group_head, bin_group) bin_groups; 11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct bin_group { 11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_ENTRY(bin_group) link; 11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section *section; 12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_section_data *bsd; 12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Groups that (in parallel) logically come immediately after this 12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * group's section. 12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_groups follow_groups; 12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} bin_group; 12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Recursive function to find group containing named section. */ 12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic bin_group * 13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgfind_group_by_name(bin_groups *groups, const char *name) 13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group *group, *found; 13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_FOREACH(group, groups, link) { 13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (strcmp(yasm_section_get_name(group->section), name) == 0) 13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return group; 13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Recurse to loop through follow groups */ 13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org found = find_group_by_name(&group->follow_groups, name); 13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (found) 13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return found; 14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Recursive function to find group. Returns NULL if not found. */ 14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic bin_group * 14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgfind_group_by_section(bin_groups *groups, yasm_section *section) 14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group *group, *found; 14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_FOREACH(group, groups, link) { 15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (group->section == section) 15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return group; 15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Recurse to loop through follow groups */ 15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org found = find_group_by_section(&group->follow_groups, section); 15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (found) 15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return found; 15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 160a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org#if 0 161a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org/* Debugging function */ 16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgprint_groups(const bin_groups *groups, int indent_level) 16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group *group; 16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_FOREACH(group, groups, link) { 16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org printf("%*sSection `%s':\n", indent_level, "", 16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_get_name(group->section)); 16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_section_data_print(group->bsd, stdout, indent_level+1); 17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!TAILQ_EMPTY(&group->follow_groups)) { 17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org printf("%*sFollowing groups:\n", indent_level, ""); 17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org print_groups(&group->follow_groups, indent_level+1); 17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 176a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org#endif 17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_group_destroy(/*@only@*/ bin_group *group) 18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group *follow, *group_temp; 18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_FOREACH_SAFE(follow, &group->follow_groups, link, group_temp) 18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group_destroy(follow); 18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(group); 18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct bin_objfmt_output_info { 18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_object *object; 18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarns *errwarns; 19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@dependent@*/ FILE *f; 19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ unsigned char *buf; 19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@observer@*/ const yasm_section *sect; 19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long start; /* what normal variables go against */ 19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *origin; 19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *tmp_intn; /* temporary working intnum */ 19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_groups lma_groups, vma_groups; 19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} bin_objfmt_output_info; 20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_objfmt_check_sym(yasm_symrec *sym, /*@null@*/ void *d) 20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ bin_objfmt_output_info *info = (bin_objfmt_output_info *)d; 20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_sym_vis vis = yasm_symrec_get_visibility(sym); 20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(info != NULL); 20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Don't check internally-generated symbols. Only internally generated 20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * symbols have symrec data, so simply check for its presence. 21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_symrec_get_data(sym, &bin_symrec_data_cb)) 21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (vis & YASM_SYM_EXTERN) { 21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_GENERAL, 21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("binary object format does not support extern variables")); 21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_decl_line(sym)); 21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (vis & YASM_SYM_GLOBAL) { 21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_GENERAL, 22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("binary object format does not support global variables")); 22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_decl_line(sym)); 22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (vis & YASM_SYM_COMMON) { 22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_TYPE, 22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("binary object format does not support common variables")); 22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_decl_line(sym)); 22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_lma_create_group(yasm_section *sect, /*@null@*/ void *d) 23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_output_info *info = (bin_objfmt_output_info *)d; 23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_section_data *bsd = yasm_section_get_data(sect, &bin_section_data_cb); 23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long align = yasm_section_get_align(sect); 23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group *group; 23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(info != NULL); 23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(bsd != NULL); 24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org group = yasm_xmalloc(sizeof(bin_group)); 24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org group->section = sect; 24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org group->bsd = bsd; 24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_INIT(&group->follow_groups); 24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Determine section alignment as necessary. */ 24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!bsd->align) 24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd->align = yasm_intnum_create_uint(align > 4 ? align : 4); 24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else { 25045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *align_intn = yasm_intnum_create_uint(align); 25145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_intnum_compare(align_intn, bsd->align) > 0) { 25245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_GENERAL, 25345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("section `%s' internal align of %lu is greater than `%s' of %lu; using `%s'"), 25445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_get_name(sect), 25545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_get_uint(align_intn), 25645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("align"), 25745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_get_uint(bsd->align), 25845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("align")); 25945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(info->errwarns, 0); 26045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 26145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(align_intn); 26245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 26345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 26445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Calculate section integer start. */ 26545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bsd->start) { 26645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd->istart = yasm_expr_get_intnum(&bsd->start, 0); 26745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!bsd->istart) { 26845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_TOO_COMPLEX, 26945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("start expression is too complex")); 27045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(info->errwarns, bsd->start->line); 27145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 27245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else 27345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd->istart = yasm_intnum_copy(bsd->istart); 27445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else 27545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd->istart = NULL; 27645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 27745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Calculate section integer vstart. */ 27845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bsd->vstart) { 27945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd->ivstart = yasm_expr_get_intnum(&bsd->vstart, 0); 28045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!bsd->ivstart) { 28145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_TOO_COMPLEX, 28245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("vstart expression is too complex")); 28345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(info->errwarns, bsd->vstart->line); 28445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 28545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else 28645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd->ivstart = yasm_intnum_copy(bsd->ivstart); 28745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else 28845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd->ivstart = NULL; 28945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 29045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Calculate section integer length. */ 29145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd->length = yasm_calc_bc_dist(yasm_section_bcs_first(sect), 29245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_bcs_last(sect)); 29345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 29445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_INSERT_TAIL(&info->lma_groups, group, link); 29545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 29645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 29745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 29845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 29945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_vma_create_group(yasm_section *sect, /*@null@*/ void *d) 30045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 30145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_output_info *info = (bin_objfmt_output_info *)d; 30245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_section_data *bsd = yasm_section_get_data(sect, &bin_section_data_cb); 30345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group *group; 30445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 30545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(info != NULL); 30645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(bsd != NULL); 30745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 30845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org group = yasm_xmalloc(sizeof(bin_group)); 30945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org group->section = sect; 31045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org group->bsd = bsd; 31145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_INIT(&group->follow_groups); 31245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 31345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_INSERT_TAIL(&info->vma_groups, group, link); 31445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 31545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 31645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 31745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Calculates new start address based on alignment constraint. 31845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Start is modified (rounded up) to the closest aligned value greater than 31945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * what was passed in. 32045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Align must be a power of 2. 32145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 32245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 32345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_objfmt_align(yasm_intnum *start, const yasm_intnum *align) 32445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 32545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Because alignment is always a power of two, we can use some bit 32645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * trickery to do this easily. 32745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 32845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *align_intn = 32945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_create_uint(yasm_intnum_get_uint(align)-1); 33045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(align_intn, YASM_EXPR_AND, start); 33145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!yasm_intnum_is_zero(align_intn)) { 33245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* start = (start & ~(align-1)) + align; */ 33345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_set_uint(align_intn, yasm_intnum_get_uint(align)-1); 33445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(align_intn, YASM_EXPR_NOT, NULL); 33545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(align_intn, YASM_EXPR_AND, start); 33645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_set(start, align); 33745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(start, YASM_EXPR_ADD, align_intn); 33845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 33945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(align_intn); 34045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 34145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 34245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Recursive function to assign start addresses. 34345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Updates start, last, and vdelta parameters as it goes along. 34445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The tmp parameter is just a working intnum so one doesn't have to be 34545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * locally allocated for this purpose. 34645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 34745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 34845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orggroup_assign_start_recurse(bin_group *group, yasm_intnum *start, 34945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *last, yasm_intnum *vdelta, 35045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *tmp, yasm_errwarns *errwarns) 35145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 35245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group *follow_group; 35345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 35445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Determine LMA */ 35545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (group->bsd->istart) { 35645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_set(group->bsd->istart, start); 35745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (group->bsd->align) { 35845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_align(group->bsd->istart, group->bsd->align); 35945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_intnum_compare(start, group->bsd->istart) != 0) { 36045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_GENERAL, 36145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("start inconsistent with align; using aligned value")); 36245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(errwarns, group->bsd->start->line); 36345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 36445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 36545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 36645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org group->bsd->istart = yasm_intnum_copy(start); 36745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (group->bsd->align != 0) 36845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_align(group->bsd->istart, group->bsd->align); 36945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 37045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 37145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Determine VMA if either just valign specified or if no v* specified */ 37245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!group->bsd->vstart) { 37345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!group->bsd->vfollows && !group->bsd->valign) { 37445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* No v* specified, set VMA=LMA+vdelta. */ 37545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org group->bsd->ivstart = yasm_intnum_copy(group->bsd->istart); 37645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(group->bsd->ivstart, YASM_EXPR_ADD, vdelta); 37745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (!group->bsd->vfollows) { 37845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Just valign specified: set VMA=LMA+vdelta, align VMA, then add 37945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * delta between unaligned and aligned to vdelta parameter. 38045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 38145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org group->bsd->ivstart = yasm_intnum_copy(group->bsd->istart); 38245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(group->bsd->ivstart, YASM_EXPR_ADD, vdelta); 38345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_set(tmp, group->bsd->ivstart); 38445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_align(group->bsd->ivstart, group->bsd->valign); 38545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(vdelta, YASM_EXPR_ADD, group->bsd->ivstart); 38645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(vdelta, YASM_EXPR_SUB, tmp); 38745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 38845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 38945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 39045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Find the maximum end value */ 39145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_set(tmp, group->bsd->istart); 39245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(tmp, YASM_EXPR_ADD, group->bsd->length); 39345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_intnum_compare(tmp, last) > 0) /* tmp > last */ 39445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_set(last, tmp); 39545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 39645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Recurse for each following group. */ 39745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_FOREACH(follow_group, &group->follow_groups, link) { 39845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Following sections have to follow this one, 39945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * so add length to start. 40045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 40145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_set(start, group->bsd->istart); 40245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(start, YASM_EXPR_ADD, group->bsd->length); 40345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 40445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org group_assign_start_recurse(follow_group, start, last, vdelta, tmp, 40545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org errwarns); 40645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 40745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 40845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 40945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Recursive function to assign start addresses. 41045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Updates start parameter as it goes along. 41145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The tmp parameter is just a working intnum so one doesn't have to be 41245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * locally allocated for this purpose. 41345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 41445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 41545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orggroup_assign_vstart_recurse(bin_group *group, yasm_intnum *start, 41645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarns *errwarns) 41745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 41845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group *follow_group; 41945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 42045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Determine VMA section alignment as necessary. 42145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Default to LMA alignment if not specified. 42245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 42345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!group->bsd->valign) 42445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org group->bsd->valign = yasm_intnum_copy(group->bsd->align); 42545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else { 42645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long align = yasm_section_get_align(group->section); 42745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *align_intn = yasm_intnum_create_uint(align); 42845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_intnum_compare(align_intn, group->bsd->valign) > 0) { 42945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_GENERAL, 43045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("section `%s' internal align of %lu is greater than `%s' of %lu; using `%s'"), 43145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_get_name(group->section), 43245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_get_uint(align_intn), 43345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("valign"), 43445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_get_uint(group->bsd->valign), 43545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("valign")); 43645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(errwarns, 0); 43745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 43845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(align_intn); 43945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 44045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 44145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Determine VMA */ 44245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (group->bsd->ivstart) { 44345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_set(group->bsd->ivstart, start); 44445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (group->bsd->valign) { 44545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_align(group->bsd->ivstart, group->bsd->valign); 44645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_intnum_compare(start, group->bsd->ivstart) != 0) { 44745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_VALUE, 44845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("vstart inconsistent with valign")); 44945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(errwarns, group->bsd->vstart->line); 45045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 45145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 45245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 45345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org group->bsd->ivstart = yasm_intnum_copy(start); 45445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (group->bsd->valign) 45545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_align(group->bsd->ivstart, group->bsd->valign); 45645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 45745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 45845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Recurse for each following group. */ 45945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_FOREACH(follow_group, &group->follow_groups, link) { 46045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Following sections have to follow this one, 46145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * so add length to start. 46245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 46345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_set(start, group->bsd->ivstart); 46445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(start, YASM_EXPR_ADD, group->bsd->length); 46545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 46645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org group_assign_vstart_recurse(follow_group, start, errwarns); 46745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 46845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 46945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 47045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic /*@null@*/ const yasm_intnum * 47145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgget_ssym_value(yasm_symrec *sym) 47245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 47345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_symrec_data *bsymd = yasm_symrec_get_data(sym, &bin_symrec_data_cb); 47445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_section_data *bsd; 47545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 47645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!bsymd) 47745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 47845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 47945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd = yasm_section_get_data(bsymd->section, &bin_section_data_cb); 48045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(bsd != NULL); 48145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 48245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (bsymd->which) { 48345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case SSYM_START: return bsd->istart; 48445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case SSYM_VSTART: return bsd->ivstart; 48545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case SSYM_LENGTH: return bsd->length; 48645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 48745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 48845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 48945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 49045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic /*@only@*/ yasm_expr * 49145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_objfmt_expr_xform(/*@returned@*/ /*@only@*/ yasm_expr *e, 49245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@unused@*/ /*@null@*/ void *d) 49345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 49445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int i; 49545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0; i<e->numterms; i++) { 49645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@dependent@*/ yasm_section *sect; 49745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc; 49845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ yasm_intnum *dist; 49945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ const yasm_intnum *ssymval; 50045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 50145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Transform symrecs or precbcs that reference sections into 50245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * vstart + intnum(dist). 50345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 50445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (((e->terms[i].type == YASM_EXPR_SYM && 50545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec_get_label(e->terms[i].data.sym, &precbc)) || 50645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (e->terms[i].type == YASM_EXPR_PRECBC && 50745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (precbc = e->terms[i].data.precbc))) && 50845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (sect = yasm_bc_get_section(precbc)) && 50945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (dist = yasm_calc_bc_dist(yasm_section_bcs_first(sect), precbc))) { 51045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_section_data *bsd; 51145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd = yasm_section_get_data(sect, &bin_section_data_cb); 51245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(bsd != NULL); 51345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(dist, YASM_EXPR_ADD, bsd->ivstart); 51445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org e->terms[i].type = YASM_EXPR_INT; 51545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org e->terms[i].data.intn = dist; 51645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 51745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 51845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Transform our special symrecs into the appropriate value */ 51945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (e->terms[i].type == YASM_EXPR_SYM && 52045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (ssymval = get_ssym_value(e->terms[i].data.sym))) { 52145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org e->terms[i].type = YASM_EXPR_INT; 52245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org e->terms[i].data.intn = yasm_intnum_copy(ssymval); 52345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 52445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 52545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 52645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return e; 52745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 52845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 52945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct map_output_info { 53045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* address width */ 53145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int bytes; 53245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 53345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* intnum output static data areas */ 53445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned char *buf; 53545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *intn; 53645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 53745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* symrec output information */ 53845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long count; 53945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section *section; /* NULL for EQUs */ 54045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 54145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_object *object; /* object */ 54245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org FILE *f; /* map output file */ 54345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} map_output_info; 54445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 54545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 54645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgmap_prescan_bytes(yasm_section *sect, void *d) 54745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 54845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_section_data *bsd = yasm_section_get_data(sect, &bin_section_data_cb); 54945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_output_info *info = (map_output_info *)d; 55045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 55145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(bsd != NULL); 55245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(info != NULL); 55345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 55445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (!yasm_intnum_check_size(bsd->length, info->bytes * 8, 0, 0)) 55545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->bytes *= 2; 55645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (!yasm_intnum_check_size(bsd->istart, info->bytes * 8, 0, 0)) 55745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->bytes *= 2; 55845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (!yasm_intnum_check_size(bsd->ivstart, info->bytes * 8, 0, 0)) 55945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->bytes *= 2; 56045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 56145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 56245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 56345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 56445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 56545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgmap_print_intnum(const yasm_intnum *intn, map_output_info *info) 56645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 56745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t i; 56845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_get_sized(intn, info->buf, info->bytes, info->bytes*8, 0, 0, 56945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 0); 57045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=info->bytes; i != 0; i--) 57145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, "%02X", info->buf[i-1]); 57245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 57345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 57445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 57545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgmap_sections_summary(bin_groups *groups, map_output_info *info) 57645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 57745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group *group; 57845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_FOREACH(group, groups, link) { 57945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_section_data *bsd = group->bsd; 58045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 58145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(bsd != NULL); 58245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(info != NULL); 58345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 58445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_print_intnum(bsd->ivstart, info); 58545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, " "); 58645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 58745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_set(info->intn, bsd->ivstart); 58845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(info->intn, YASM_EXPR_ADD, bsd->length); 58945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_print_intnum(info->intn, info); 59045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, " "); 59145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 59245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_print_intnum(bsd->istart, info); 59345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, " "); 59445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 59545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_set(info->intn, bsd->istart); 59645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(info->intn, YASM_EXPR_ADD, bsd->length); 59745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_print_intnum(info->intn, info); 59845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, " "); 59945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 60045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_print_intnum(bsd->length, info); 60145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, " "); 60245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 60345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, "%-*s", 10, bsd->bss ? "nobits" : "progbits"); 60445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, "%s\n", yasm_section_get_name(group->section)); 60545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 60645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Recurse to loop through follow groups */ 60745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_sections_summary(&group->follow_groups, info); 60845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 60945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 61045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 61145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 61245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgmap_sections_detail(bin_groups *groups, map_output_info *info) 61345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 61445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group *group; 61545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_FOREACH(group, groups, link) { 61645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_section_data *bsd = group->bsd; 61745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t i; 61845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *s; 61945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 62045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s = yasm_section_get_name(group->section); 62145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, "---- Section %s ", s); 62245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0; i<(65-strlen(s)); i++) 62345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fputc('-', info->f); 62445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 62545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, "\n\nclass: %s", 62645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd->bss ? "nobits" : "progbits"); 62745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, "\nlength: "); 62845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_print_intnum(bsd->length, info); 62945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, "\nstart: "); 63045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_print_intnum(bsd->istart, info); 63145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, "\nalign: "); 63245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_print_intnum(bsd->align, info); 63345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, "\nfollows: %s", 63445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd->follows ? bsd->follows : "not defined"); 63545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, "\nvstart: "); 63645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_print_intnum(bsd->ivstart, info); 63745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, "\nvalign: "); 63845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_print_intnum(bsd->valign, info); 63945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, "\nvfollows: %s\n\n", 64045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd->vfollows ? bsd->vfollows : "not defined"); 64145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 64245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Recurse to loop through follow groups */ 64345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_sections_detail(&group->follow_groups, info); 64445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 64545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 64645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 64745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 64845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgmap_symrec_count(yasm_symrec *sym, void *d) 64945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 65045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_output_info *info = (map_output_info *)d; 65145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@dependent@*/ yasm_bytecode *precbc; 65245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 65345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(info != NULL); 65445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 65545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* TODO: autodetect wider size */ 65645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!info->section && yasm_symrec_get_equ(sym)) { 65745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->count++; 65845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (yasm_symrec_get_label(sym, &precbc) && 65945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_bc_get_section(precbc) == info->section) { 66045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->count++; 66145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 66245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 66345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 66445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 66545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 66645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgmap_symrec_output(yasm_symrec *sym, void *d) 66745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 66845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_output_info *info = (map_output_info *)d; 66945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const yasm_expr *equ; 67045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@dependent@*/ yasm_bytecode *precbc; 67145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ char *name = yasm_symrec_get_global_name(sym, info->object); 67245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 67345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(info != NULL); 67445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 67545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!info->section && (equ = yasm_symrec_get_equ(sym))) { 67645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr *realequ = yasm_expr_copy(equ); 67745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org realequ = yasm_expr__level_tree 67845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (realequ, 1, 1, 1, 0, bin_objfmt_expr_xform, NULL); 67945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_set(info->intn, yasm_expr_get_intnum(&realequ, 0)); 68045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_destroy(realequ); 68145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_print_intnum(info->intn, info); 68245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, " %s\n", name); 68345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (yasm_symrec_get_label(sym, &precbc) && 68445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_bc_get_section(precbc) == info->section) { 68545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_section_data *bsd = 68645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_get_data(info->section, &bin_section_data_cb); 68745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 68845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Real address */ 68945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_set_uint(info->intn, yasm_bc_next_offset(precbc)); 69045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(info->intn, YASM_EXPR_ADD, bsd->istart); 69145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_print_intnum(info->intn, info); 69245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, " "); 69345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 69445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Virtual address */ 69545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_set_uint(info->intn, yasm_bc_next_offset(precbc)); 69645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(info->intn, YASM_EXPR_ADD, bsd->ivstart); 69745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_print_intnum(info->intn, info); 69845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 69945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Name */ 70045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, " %s\n", name); 70145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 70245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(name); 70345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 70445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 70545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 70645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 70745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgmap_sections_symbols(bin_groups *groups, map_output_info *info) 70845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 70945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group *group; 71045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_FOREACH(group, groups, link) { 71145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->count = 0; 71245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->section = group->section; 71345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symtab_traverse(info->object->symtab, info, map_symrec_count); 71445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 71545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (info->count > 0) { 71645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *s = yasm_section_get_name(group->section); 71745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t i; 71845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, "---- Section %s ", s); 71945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0; i<(65-strlen(s)); i++) 72045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fputc('-', info->f); 72145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, "\n\n%-*s%-*s%s\n", 72245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->bytes*2+2, "Real", 72345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->bytes*2+2, "Virtual", 72445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "Name"); 72545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symtab_traverse(info->object->symtab, info, 72645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_symrec_output); 72745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(info->f, "\n\n"); 72845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 72945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 73045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Recurse to loop through follow groups */ 73145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_sections_symbols(&group->follow_groups, info); 73245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 73345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 73445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 73545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 73645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgoutput_map(bin_objfmt_output_info *info) 73745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 73845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)info->object->objfmt; 73945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org FILE *f; 74045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int i; 74145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_output_info mapinfo; 74245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 74345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (objfmt_bin->map_flags == NO_MAP) 74445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 74545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 74645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (objfmt_bin->map_flags == MAP_NONE) 74745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_bin->map_flags = MAP_BRIEF; /* default to brief */ 74845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 74945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!objfmt_bin->map_filename) 75045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org f = stdout; /* default to stdout */ 75145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else { 75245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org f = fopen(objfmt_bin->map_filename, "wt"); 75345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!f) { 75445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_GENERAL, 75545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("unable to open map file `%s'"), 75645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_bin->map_filename); 75745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(info->errwarns, 0); 75845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 75945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 76045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 76145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 76245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mapinfo.object = info->object; 76345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mapinfo.f = f; 76445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 76545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Temporary intnum */ 76645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mapinfo.intn = info->tmp_intn; 76745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 76845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Prescan all values to figure out what width we should make the output 76945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * fields. Start with a minimum of 4. 77045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 77145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mapinfo.bytes = 4; 77245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (!yasm_intnum_check_size(info->origin, mapinfo.bytes * 8, 0, 0)) 77345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mapinfo.bytes *= 2; 77445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_object_sections_traverse(info->object, &mapinfo, map_prescan_bytes); 77545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mapinfo.buf = yasm_xmalloc(mapinfo.bytes); 77645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 77745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n- YASM Map file "); 77845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0; i<63; i++) 77945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fputc('-', f); 78045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n\nSource file: %s\n", info->object->src_filename); 78145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "Output file: %s\n\n", info->object->obj_filename); 78245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 78345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "-- Program origin "); 78445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0; i<61; i++) 78545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fputc('-', f); 78645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n\n"); 78745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_print_intnum(info->origin, &mapinfo); 78845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n\n"); 78945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 79045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (objfmt_bin->map_flags & MAP_BRIEF) { 79145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "-- Sections (summary) "); 79245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0; i<57; i++) 79345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fputc('-', f); 79445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n\n%-*s%-*s%-*s%-*s%-*s%-*s%s\n", 79545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mapinfo.bytes*2+2, "Vstart", 79645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mapinfo.bytes*2+2, "Vstop", 79745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mapinfo.bytes*2+2, "Start", 79845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mapinfo.bytes*2+2, "Stop", 79945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mapinfo.bytes*2+2, "Length", 80045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 10, "Class", "Name"); 80145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 80245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_sections_summary(&info->lma_groups, &mapinfo); 80345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n"); 80445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 80545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 80645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (objfmt_bin->map_flags & MAP_SECTIONS) { 80745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "-- Sections (detailed) "); 80845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0; i<56; i++) 80945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fputc('-', f); 81045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n\n"); 81145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_sections_detail(&info->lma_groups, &mapinfo); 81245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 81345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 81445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (objfmt_bin->map_flags & MAP_SYMBOLS) { 81545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "-- Symbols "); 81645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0; i<68; i++) 81745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fputc('-', f); 81845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n\n"); 81945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 82045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* We do two passes for EQU and each section; the first pass 82145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * determines the byte width to use for the value and whether any 82245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * symbols are present, the second pass actually outputs the text. 82345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 82445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 82545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* EQUs */ 82645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mapinfo.count = 0; 82745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mapinfo.section = NULL; 82845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symtab_traverse(info->object->symtab, &mapinfo, map_symrec_count); 82945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 83045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (mapinfo.count > 0) { 83145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "---- No Section "); 83245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0; i<63; i++) 83345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fputc('-', f); 83445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n\n%-*s%s\n", mapinfo.bytes*2+2, "Value", "Name"); 83545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symtab_traverse(info->object->symtab, &mapinfo, 83645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_symrec_output); 83745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n\n"); 83845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 83945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 84045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Other sections */ 84145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org map_sections_symbols(&info->lma_groups, &mapinfo); 84245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 84345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 84445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (f != stdout) 84545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fclose(f); 84645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 84745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(mapinfo.buf); 84845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 84945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 85045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Check for LMA overlap using a simple N^2 algorithm. */ 85145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 85245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgcheck_lma_overlap(yasm_section *sect, /*@null@*/ void *d) 85345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 85445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_section_data *bsd, *bsd2; 85545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section *other = (yasm_section *)d; 85645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *overlap; 85745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 85845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!d) 85945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return yasm_object_sections_traverse(yasm_section_get_object(sect), 86045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sect, check_lma_overlap); 86145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (sect == other) 86245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 86345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 86445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd = yasm_section_get_data(sect, &bin_section_data_cb); 86545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd2 = yasm_section_get_data(other, &bin_section_data_cb); 86645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 86745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_intnum_is_zero(bsd->length) || 86845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_is_zero(bsd2->length)) 86945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 87045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 87145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_intnum_compare(bsd->istart, bsd2->istart) <= 0) { 87245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org overlap = yasm_intnum_copy(bsd->istart); 87345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(overlap, YASM_EXPR_ADD, bsd->length); 87445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(overlap, YASM_EXPR_SUB, bsd2->istart); 87545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 87645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org overlap = yasm_intnum_copy(bsd2->istart); 87745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(overlap, YASM_EXPR_ADD, bsd2->length); 87845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(overlap, YASM_EXPR_SUB, bsd->istart); 87945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 88045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 88145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_intnum_sign(overlap) > 0) { 88245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_GENERAL, 88345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("sections `%s' and `%s' overlap by %lu bytes"), 88445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_get_name(sect), 88545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_get_name(other), 88645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_get_uint(overlap)); 88745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(overlap); 88845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 88945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 89045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 89145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(overlap); 89245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 89345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 89445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 89545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 89645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_objfmt_output_value(yasm_value *value, unsigned char *buf, 89745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned int destsize, 89845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@unused@*/ unsigned long offset, yasm_bytecode *bc, 89945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int warn, /*@null@*/ void *d) 90045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 90145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ bin_objfmt_output_info *info = (bin_objfmt_output_info *)d; 90245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc; 90345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@dependent@*/ yasm_section *sect; 90445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 90545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(info != NULL); 90645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 90745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Binary objects we need to resolve against object, not against section. */ 90845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (value->rel) { 90945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned int rshift = (unsigned int)value->rshift; 91045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr *syme; 91145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ const yasm_intnum *ssymval; 91245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 91345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_symrec_is_abs(value->rel)) { 91445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org syme = yasm_expr_create_ident(yasm_expr_int( 91545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_create_uint(0)), bc->line); 91645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (yasm_symrec_get_label(value->rel, &precbc) 91745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && (sect = yasm_bc_get_section(precbc))) { 91845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org syme = yasm_expr_create_ident(yasm_expr_sym(value->rel), bc->line); 91945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if ((ssymval = get_ssym_value(value->rel))) { 92045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org syme = yasm_expr_create_ident(yasm_expr_int( 92145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_copy(ssymval)), bc->line); 92245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else 92345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org goto done; 92445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 92545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Handle PC-relative */ 92645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (value->curpos_rel) { 92745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr *sube; 92845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sube = yasm_expr_create(YASM_EXPR_SUB, yasm_expr_precbc(bc), 92945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_int(yasm_intnum_create_uint(bc->len*bc->mult_int)), 93045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bc->line); 93145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org syme = yasm_expr_create(YASM_EXPR_SUB, yasm_expr_expr(syme), 93245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_expr(sube), bc->line); 93345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org value->curpos_rel = 0; 93445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org value->ip_rel = 0; 93545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 93645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 93745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (value->rshift > 0) 93845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org syme = yasm_expr_create(YASM_EXPR_SHR, yasm_expr_expr(syme), 93945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_int(yasm_intnum_create_uint(rshift)), bc->line); 94045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 94145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Add into absolute portion */ 94245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!value->abs) 94345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org value->abs = syme; 94445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 94545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org value->abs = 94645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_create(YASM_EXPR_ADD, yasm_expr_expr(value->abs), 94745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_expr(syme), bc->line); 94845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org value->rel = NULL; 94945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org value->rshift = 0; 95045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 95145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgdone: 95245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Simplify absolute portion of value, transforming symrecs */ 95345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (value->abs) 95445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org value->abs = yasm_expr__level_tree 95545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (value->abs, 1, 1, 1, 0, bin_objfmt_expr_xform, NULL); 95645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 95745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Output */ 95845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (yasm_value_output_basic(value, buf, destsize, bc, warn, 95945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info->object->arch)) { 96045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case -1: 96145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 96245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case 0: 96345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 96445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org default: 96545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 96645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 96745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 96845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Couldn't output, assume it contains an external reference. */ 96945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_GENERAL, 97045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("binary object format does not support external references")); 97145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 97245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 97345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 97445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 97545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_objfmt_output_bytecode(yasm_bytecode *bc, /*@null@*/ void *d) 97645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 97745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ bin_objfmt_output_info *info = (bin_objfmt_output_info *)d; 97845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ /*@only@*/ unsigned char *bigbuf; 97945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long size = REGULAR_OUTBUF_SIZE; 98045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int gap; 98145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 98245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(info != NULL); 98345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 98445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &gap, info, 98545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_output_value, NULL); 98645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 98745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Don't bother doing anything else if size ended up being 0. */ 98845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (size == 0) { 98945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bigbuf) 99045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(bigbuf); 99145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 99245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 99345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 99445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Warn that gaps are converted to 0 and write out the 0's. */ 99545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (gap) { 99645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long left; 99745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_UNINIT_CONTENTS, 99845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("uninitialized space declared in code/data section: zeroing")); 99945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Write out in chunks */ 100045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org memset(info->buf, 0, REGULAR_OUTBUF_SIZE); 100145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org left = size; 100245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (left > REGULAR_OUTBUF_SIZE) { 100345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(info->buf, REGULAR_OUTBUF_SIZE, 1, info->f); 100445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org left -= REGULAR_OUTBUF_SIZE; 100545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 100645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(info->buf, left, 1, info->f); 100745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 100845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Output buf (or bigbuf if non-NULL) to file */ 100945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(bigbuf ? bigbuf : info->buf, (size_t)size, 1, info->f); 101045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 101145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 101245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* If bigbuf was allocated, free it */ 101345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bigbuf) 101445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(bigbuf); 101545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 101645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 101745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 101845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 101945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Check to ensure bytecode is res* (for BSS sections) */ 102045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 102145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_objfmt_no_output_bytecode(yasm_bytecode *bc, /*@null@*/ void *d) 102245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 102345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ bin_objfmt_output_info *info = (bin_objfmt_output_info *)d; 102445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ /*@only@*/ unsigned char *bigbuf; 102545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long size = REGULAR_OUTBUF_SIZE; 102645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int gap; 102745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 102845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(info != NULL); 102945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 103045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &gap, info, 103145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_output_value, NULL); 103245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 103345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* If bigbuf was allocated, free it */ 103445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bigbuf) 103545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(bigbuf); 103645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 103745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Don't bother doing anything else if size ended up being 0. */ 103845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (size == 0) 103945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 104045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 104145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Warn if not a gap. */ 104245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!gap) { 104345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_GENERAL, 104445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("initialized space declared in nobits section: ignoring")); 104545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 104645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 104745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 104845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 104945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 105045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 105145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_objfmt_output_section(yasm_section *sect, /*@null@*/ void *d) 105245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 105345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_section_data *bsd = yasm_section_get_data(sect, &bin_section_data_cb); 105445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ bin_objfmt_output_info *info = (bin_objfmt_output_info *)d; 105545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 105645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(bsd != NULL); 105745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(info != NULL); 105845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 105945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bsd->bss) { 106045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_bcs_traverse(sect, info->errwarns, 106145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info, bin_objfmt_no_output_bytecode); 106245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 106345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_set(info->tmp_intn, bsd->istart); 106445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_calc(info->tmp_intn, YASM_EXPR_SUB, info->origin); 106545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_intnum_sign(info->tmp_intn) < 0) { 106645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_VALUE, 106745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("section `%s' starts before origin (ORG)"), 106845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_get_name(sect)); 106945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(info->errwarns, 0); 107045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 107145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 107245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!yasm_intnum_check_size(info->tmp_intn, sizeof(long)*8, 0, 1)) { 107345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_VALUE, 107445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("section `%s' start value too large"), 107545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_get_name(sect)); 107645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(info->errwarns, 0); 107745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 107845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 107945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fseek(info->f, yasm_intnum_get_int(info->tmp_intn) + info->start, 108045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SEEK_SET) < 0) 108145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm__fatal(N_("could not seek on output file")); 108245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_bcs_traverse(sect, info->errwarns, 108345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info, bin_objfmt_output_bytecode); 108445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 108545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 108645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 108745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 108845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 108945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 109045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_objfmt_cleanup(bin_objfmt_output_info *info) 109145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 109245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group *group, *group_temp; 109345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 109445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(info->buf); 109545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(info->origin); 109645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(info->tmp_intn); 109745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 109845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_FOREACH_SAFE(group, &info->lma_groups, link, group_temp) 109945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group_destroy(group); 110045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 110145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_FOREACH_SAFE(group, &info->vma_groups, link, group_temp) 110245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group_destroy(group); 110345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 110445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 110545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 110645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_objfmt_output(yasm_object *object, FILE *f, /*@unused@*/ int all_syms, 110745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarns *errwarns) 110845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 110945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)object->objfmt; 111045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_output_info info; 111145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group *group, *lma_group, *vma_group, *group_temp; 111245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *start, *last, *vdelta; 111345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_groups unsorted_groups, bss_groups; 111445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 111545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.start = ftell(f); 111645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 111745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Set ORG to 0 unless otherwise specified */ 111845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (objfmt_bin->org) { 111945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.origin = yasm_expr_get_intnum(&objfmt_bin->org, 0); 112045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!info.origin) { 112145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_TOO_COMPLEX, 112245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("ORG expression is too complex")); 112345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(errwarns, objfmt_bin->org->line); 112445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 112545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 112645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_intnum_sign(info.origin) < 0) { 112745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_VALUE, N_("ORG expression is negative")); 112845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(errwarns, objfmt_bin->org->line); 112945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 113045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 113145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.origin = yasm_intnum_copy(info.origin); 113245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else 113345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.origin = yasm_intnum_create_uint(0); 113445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 113545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.object = object; 113645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.errwarns = errwarns; 113745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.f = f; 113845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.buf = yasm_xmalloc(REGULAR_OUTBUF_SIZE); 113945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.tmp_intn = yasm_intnum_create_uint(0); 114045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_INIT(&info.lma_groups); 114145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_INIT(&info.vma_groups); 114245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 114345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Check symbol table */ 114445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symtab_traverse(object->symtab, &info, bin_objfmt_check_sym); 114545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 114645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Create section groups */ 114745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_object_sections_traverse(object, &info, bin_lma_create_group)) { 114845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_cleanup(&info); 114945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; /* error detected */ 115045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 115145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 115245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Determine section order according to LMA. 115345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Sections can be ordered either by (priority): 115445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * - follows 115545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * - start 115645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * - progbits/nobits setting 115745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * - order in the input file 115845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 115945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 116045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Look at each group with follows specified, and find the section 116145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * that group is supposed to follow. 116245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 116345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_FOREACH_SAFE(lma_group, &info.lma_groups, link, group_temp) { 116445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (lma_group->bsd->follows) { 116545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group *found; 116645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Need to find group containing section this section follows. */ 116745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org found = 116845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org find_group_by_name(&info.lma_groups, lma_group->bsd->follows); 116945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!found) { 117045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_VALUE, 117145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("section `%s' follows an invalid or unknown section `%s'"), 117245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_get_name(lma_group->section), 117345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org lma_group->bsd->follows); 117445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(errwarns, 0); 117545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_cleanup(&info); 117645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 117745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 117845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 117945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Check for loops */ 118045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (lma_group->section == found->section || 118145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org find_group_by_section(&lma_group->follow_groups, 118245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org found->section)) { 118345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_VALUE, 118445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("follows loop between section `%s' and section `%s'"), 118545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_get_name(lma_group->section), 118645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_get_name(found->section)); 118745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(errwarns, 0); 118845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_cleanup(&info); 118945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 119045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 119145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 119245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Remove this section from main lma groups list */ 119345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_REMOVE(&info.lma_groups, lma_group, link); 119445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Add it after the section it's supposed to follow. */ 119545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_INSERT_TAIL(&found->follow_groups, lma_group, link); 119645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 119745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 119845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 119945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Sort the top-level groups according to their start address. 120045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Use Shell sort for ease of implementation. 120145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * If no start address is specified for a section, don't change the order, 120245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * and move BSS sections to a separate list so they can be moved to the 120345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * end of the lma list after all other sections are sorted. 120445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 120545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsorted_groups = info.lma_groups; /* structure copy */ 120645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_INIT(&info.lma_groups); 120745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_INIT(&bss_groups); 120845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_FOREACH_SAFE(lma_group, &unsorted_groups, link, group_temp) { 120945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group *before; 121045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 121145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!lma_group->bsd->istart) { 121245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (lma_group->bsd->bss) 121345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_INSERT_TAIL(&bss_groups, lma_group, link); 121445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 121545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_INSERT_TAIL(&info.lma_groups, lma_group, link); 121645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 121745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 121845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 121945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org before = NULL; 122045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_FOREACH(group, &info.lma_groups, link) { 122145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!group->bsd->istart) 122245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 122345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_intnum_compare(group->bsd->istart, 122445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org lma_group->bsd->istart) > 0) { 122545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org before = group; 122645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 122745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 122845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 122945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (before) 123045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_INSERT_BEFORE(before, lma_group, link); 123145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 123245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_INSERT_TAIL(&info.lma_groups, lma_group, link); 123345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 123445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 123545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Move the pure-BSS sections to the end of the LMA list. */ 123645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_FOREACH_SAFE(group, &bss_groups, link, group_temp) 123745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_INSERT_TAIL(&info.lma_groups, group, link); 123845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_INIT(&bss_groups); /* For sanity */ 123945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 124045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Assign a LMA start address to every section. 124145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Also assign VMA=LMA unless otherwise specified. 124245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 124345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * We need to assign VMA=LMA here (while walking the tree) for the case: 124445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * sect1 start=0 (size=0x11) 124545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * sect2 follows=sect1 valign=16 (size=0x104) 124645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * sect3 follows=sect2 valign=16 124745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Where the valign of sect2 will result in a sect3 vaddr higher than a 124845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * naive segment-by-segment interpretation (where sect3 and sect2 would 124945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * have a VMA overlap). 125045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 125145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Algorithm for VMA=LMA setting: 125245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Start with delta=0. 125345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * If there's no virtual attributes, we simply set VMA = LMA+delta. 125445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * If there's only valign specified, we set VMA = aligned LMA, and add 125545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * any new alignment difference to delta. 125645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 125745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * We could do the LMA start and VMA=LMA steps in two separate steps, 125845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * but it's easier to just recurse once. 125945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 126045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org start = yasm_intnum_copy(info.origin); 126145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org last = yasm_intnum_copy(info.origin); 126245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org vdelta = yasm_intnum_create_uint(0); 126345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_FOREACH(lma_group, &info.lma_groups, link) { 126445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (lma_group->bsd->istart) 126545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_set(start, lma_group->bsd->istart); 126645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org group_assign_start_recurse(lma_group, start, last, vdelta, 126745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org info.tmp_intn, errwarns); 126845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_set(start, last); 126945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 127045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(last); 127145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(vdelta); 127245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 127345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* 127445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Determine section order according to VMA 127545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 127645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 127745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Create section groups */ 127845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_object_sections_traverse(object, &info, bin_vma_create_group)) { 127945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(start); 128045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_cleanup(&info); 128145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; /* error detected */ 128245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 128345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 128445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Look at each group with vfollows specified, and find the section 128545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * that group is supposed to follow. 128645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 128745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_FOREACH_SAFE(vma_group, &info.vma_groups, link, group_temp) { 128845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (vma_group->bsd->vfollows) { 128945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_group *found; 129045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Need to find group containing section this section follows. */ 129145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org found = find_group_by_name(&info.vma_groups, 129245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org vma_group->bsd->vfollows); 129345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!found) { 129445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_VALUE, 129545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("section `%s' vfollows an invalid or unknown section `%s'"), 129645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_get_name(vma_group->section), 129745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org vma_group->bsd->vfollows); 129845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(errwarns, 0); 129945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(start); 130045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_cleanup(&info); 130145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 130245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 130345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 130445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Check for loops */ 130545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (vma_group->section == found->section || 130645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org find_group_by_section(&vma_group->follow_groups, 130745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org found->section)) { 130845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_VALUE, 130945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("vfollows loop between section `%s' and section `%s'"), 131045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_get_name(vma_group->section), 131145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_get_name(found->section)); 131245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(errwarns, 0); 131345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_cleanup(&info); 131445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 131545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 131645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 131745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Remove this section from main lma groups list */ 131845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_REMOVE(&info.vma_groups, vma_group, link); 131945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Add it after the section it's supposed to follow. */ 132045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_INSERT_TAIL(&found->follow_groups, vma_group, link); 132145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 132245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 132345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 132445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Due to the combination of steps above, we now know that all top-level 132545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * groups have integer ivstart: 132645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Vstart Vfollows Valign Handled by 132745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * No No No group_assign_start_recurse() 132845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * No No Yes group_assign_start_recurse() 132945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * No Yes - vfollows loop (above) 133045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Yes - - bin_lma_create_group() 133145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 133245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org TAILQ_FOREACH(vma_group, &info.vma_groups, link) { 133345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_set(start, vma_group->bsd->ivstart); 133445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org group_assign_vstart_recurse(vma_group, start, errwarns); 133545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 133645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 133745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Output map file */ 133845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org output_map(&info); 133945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 134045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Ensure we don't have overlapping progbits LMAs. 134145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Use a dumb O(N^2) algorithm as the number of sections is essentially 134245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * always low. 134345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 134445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm_object_sections_traverse(object, NULL, check_lma_overlap)) { 134545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarn_propagate(errwarns, 0); 134645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(start); 134745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_cleanup(&info); 134845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 134945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 135045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 135145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Output sections */ 135245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_object_sections_traverse(object, &info, bin_objfmt_output_section); 135345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 135445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Clean up */ 135545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(start); 135645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_cleanup(&info); 135745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 135845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 135945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 136045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_objfmt_destroy(yasm_objfmt *objfmt) 136145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 136245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt; 136345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (objfmt_bin->map_filename) 136445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(objfmt_bin->map_filename); 136545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_destroy(objfmt_bin->org); 136645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(objfmt); 136745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 136845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 136945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 137045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgdefine_section_symbol(yasm_symtab *symtab, yasm_section *sect, 137145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *sectname, const char *suffix, 137245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org enum bin_ssym which, unsigned long line) 137345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 137445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec *sym; 137545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_symrec_data *bsymd = yasm_xmalloc(sizeof(bin_symrec_data)); 137645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *symname = yasm_xmalloc(8+strlen(sectname)+strlen(suffix)+1); 137745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 137845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org strcpy(symname, "section."); 137945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org strcat(symname, sectname); 138045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org strcat(symname, suffix); 138145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 138245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsymd->section = sect; 138345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsymd->which = which; 138445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 138545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sym = yasm_symtab_declare(symtab, symname, YASM_SYM_EXTERN, line); 138645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(symname); 138745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec_add_data(sym, &bin_symrec_data_cb, bsymd); 138845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 138945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 1390a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.orgstatic void 1391a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.orgbin_objfmt_init_new_section(yasm_section *sect, unsigned long line) 139245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 1393a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org yasm_object *object = yasm_section_get_object(sect); 1394a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org const char *sectname = yasm_section_get_name(sect); 139545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)object->objfmt;*/ 139645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_section_data *data; 139745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 139845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data = yasm_xmalloc(sizeof(bin_section_data)); 139945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->bss = 0; 140045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->align = NULL; 140145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->valign = NULL; 140245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->start = NULL; 140345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->vstart = NULL; 140445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->follows = NULL; 140545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->vfollows = NULL; 140645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->istart = NULL; 140745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->ivstart = NULL; 140845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data->length = NULL; 140945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_add_data(sect, &bin_section_data_cb, data); 141045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 141145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org define_section_symbol(object->symtab, sect, sectname, ".start", 141245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SSYM_START, line); 141345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org define_section_symbol(object->symtab, sect, sectname, ".vstart", 141445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SSYM_VSTART, line); 141545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org define_section_symbol(object->symtab, sect, sectname, ".length", 141645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org SSYM_LENGTH, line); 141745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 141845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 141945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_section * 142045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_objfmt_add_default_section(yasm_object *object) 142145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 142245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section *retval; 142345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int isnew; 142445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 142545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org retval = yasm_object_get_general(object, ".text", 0, 1, 0, &isnew, 0); 1426a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (isnew) 142745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_set_default(retval, 1); 142845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return retval; 142945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 143045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 1431a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org/* GAS-style flags */ 1432a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.orgstatic int 1433a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.orgbin_helper_gasflags(void *obj, yasm_valparam *vp, unsigned long line, void *d, 1434a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org /*@unused@*/ uintptr_t arg) 1435a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org{ 1436a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org /* TODO */ 1437a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org return 0; 1438a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org} 1439a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org 144045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic /*@observer@*/ /*@null@*/ yasm_section * 144145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams, 144245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@unused@*/ /*@null@*/ 144345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparamhead *objext_valparams, 144445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long line) 144545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 144645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparam *vp; 144745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section *retval; 144845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int isnew; 144945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int flags_override = 0; 145045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *sectname; 145145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_section_data *bsd = NULL; 145245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 145345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct bin_section_switch_data { 145445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ /*@null@*/ char *follows; 145545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ /*@null@*/ char *vfollows; 145645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ /*@null@*/ yasm_expr *start; 145745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ /*@null@*/ yasm_expr *vstart; 145845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ /*@null@*/ yasm_intnum *align; 145945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ /*@null@*/ yasm_intnum *valign; 146045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long bss; 146145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long code; 146245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } data; 146345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 146445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org static const yasm_dir_help help[] = { 146545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "follows", 1, yasm_dir_helper_string, 146645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct bin_section_switch_data, follows), 0 }, 146745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "vfollows", 1, yasm_dir_helper_string, 146845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct bin_section_switch_data, vfollows), 0 }, 146945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "start", 1, yasm_dir_helper_expr, 147045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct bin_section_switch_data, start), 0 }, 147145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "vstart", 1, yasm_dir_helper_expr, 147245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct bin_section_switch_data, vstart), 0 }, 147345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "align", 1, yasm_dir_helper_intn, 147445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct bin_section_switch_data, align), 0 }, 147545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "valign", 1, yasm_dir_helper_intn, 147645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct bin_section_switch_data, valign), 0 }, 147745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "nobits", 0, yasm_dir_helper_flag_set, 147845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct bin_section_switch_data, bss), 1 }, 147945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "progbits", 0, yasm_dir_helper_flag_set, 148045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct bin_section_switch_data, bss), 0 }, 148145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "code", 0, yasm_dir_helper_flag_set, 148245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct bin_section_switch_data, code), 1 }, 148345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "data", 0, yasm_dir_helper_flag_set, 148445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct bin_section_switch_data, code), 0 }, 148545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "execute", 0, yasm_dir_helper_flag_set, 148645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct bin_section_switch_data, code), 1 }, 148745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "noexecute", 0, yasm_dir_helper_flag_set, 1488a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org offsetof(struct bin_section_switch_data, code), 0 }, 1489a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org { "gasflags", 1, bin_helper_gasflags, 0, 0 } 149045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org }; 149145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 149245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org vp = yasm_vps_first(valparams); 149345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sectname = yasm_vp_string(vp); 149445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!sectname) 149545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 149645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org vp = yasm_vps_next(vp); 149745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 149845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org retval = yasm_object_find_general(object, sectname); 149945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (retval) { 150045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd = yasm_section_get_data(retval, &bin_section_data_cb); 150145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert(bsd != NULL); 150245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.follows = bsd->follows; 150345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.vfollows = bsd->vfollows; 150445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.start = bsd->start; 150545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.vstart = bsd->vstart; 150645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.align = NULL; 150745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.valign = NULL; 150845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.bss = bsd->bss; 150945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.code = yasm_section_is_code(retval); 151045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else { 151145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.follows = NULL; 151245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.vfollows = NULL; 151345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.start = NULL; 151445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.vstart = NULL; 151545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.align = NULL; 151645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.valign = NULL; 151745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.bss = strcmp(sectname, ".bss") == 0; 151845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.code = strcmp(sectname, ".text") == 0; 151945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 152045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 152145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org flags_override = yasm_dir_helper(object, vp, line, help, NELEMS(help), 152245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org &data, yasm_dir_helper_valparam_warn); 152345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (flags_override < 0) 152445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; /* error occurred */ 152545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 152645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (data.start && data.follows) { 152745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_GENERAL, 152845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("cannot combine `start' and `follows' section attributes")); 152945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 153045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 153145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 153245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (data.vstart && data.vfollows) { 153345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_GENERAL, 153445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("cannot combine `vstart' and `vfollows' section attributes")); 153545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 153645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 153745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 153845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (data.align) { 153945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long align = yasm_intnum_get_uint(data.align); 154045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 154145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Alignments must be a power of two. */ 154245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!is_exp2(align)) { 154345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_VALUE, 154445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("argument to `%s' is not a power of two"), 154545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "align"); 154645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 154745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 154845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else 154945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.align = bsd ? bsd->align : NULL; 155045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 155145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (data.valign) { 155245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long valign = yasm_intnum_get_uint(data.valign); 155345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 155445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Alignments must be a power of two. */ 155545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!is_exp2(valign)) { 155645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_VALUE, 155745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("argument to `%s' is not a power of two"), 155845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "valign"); 155945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 156045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 156145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else 156245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.valign = bsd ? bsd->valign : NULL; 156345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 156445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org retval = yasm_object_get_general(object, sectname, 0, (int)data.code, 156545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (int)data.bss, &isnew, line); 156645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 1567a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org bsd = yasm_section_get_data(retval, &bin_section_data_cb); 156845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 156945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (isnew || yasm_section_is_default(retval)) { 157045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_set_default(retval, 0); 157145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 157245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 157345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Update section flags */ 157445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd->bss = data.bss; 157545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd->align = data.align; 157645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd->valign = data.valign; 157745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd->start = data.start; 157845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd->vstart = data.vstart; 157945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd->follows = data.follows; 158045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bsd->vfollows = data.vfollows; 158145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 158245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return retval; 158345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 158445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 158545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic /*@observer@*/ /*@null@*/ yasm_symrec * 158645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_objfmt_get_special_sym(yasm_object *object, const char *name, 158745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *parser) 158845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 158945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 159045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 159145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 159245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 159345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_objfmt_dir_org(yasm_object *object, 159445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ yasm_valparamhead *valparams, 159545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@unused@*/ /*@null@*/ 159645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparamhead *objext_valparams, unsigned long line) 159745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 159845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)object->objfmt; 159945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparam *vp; 160045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 160145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* We only allow a single ORG in a program. */ 160245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (objfmt_bin->org) { 160345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_GENERAL, N_("program origin redefined")); 160445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 160545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 160645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 160745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* ORG takes just a simple expression as param */ 160845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org vp = yasm_vps_first(valparams); 160945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_bin->org = yasm_vp_expr(vp, object->symtab, line); 161045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!objfmt_bin->org) { 161145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_SYNTAX, 161245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("argument to ORG must be expression")); 161345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 161445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 161545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 161645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 161745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct bin_dir_map_data { 161845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long flags; 161945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ /*@null@*/ char *filename; 162045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 162145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 162245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 162345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgdir_map_filename(void *obj, yasm_valparam *vp, unsigned long line, void *data) 162445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 162545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct bin_dir_map_data *mdata = (struct bin_dir_map_data *)data; 162645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *filename; 162745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 162845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (mdata->filename) { 162945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_GENERAL, N_("map file already specified")); 163045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 163145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 163245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 163345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org filename = yasm_vp_string(vp); 163445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!filename) { 163545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_SYNTAX, 163645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("unexpected expression in [map]")); 163745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return -1; 163845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 163945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org mdata->filename = yasm__xstrdup(filename); 164045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 164145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 164245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 164345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 164445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 164545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_objfmt_dir_map(yasm_object *object, 164645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ yasm_valparamhead *valparams, 164745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@unused@*/ /*@null@*/ 164845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_valparamhead *objext_valparams, unsigned long line) 164945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 165045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)object->objfmt; 165145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 165245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org struct bin_dir_map_data data; 165345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 165445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org static const yasm_dir_help help[] = { 165545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "all", 0, yasm_dir_helper_flag_or, 165645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct bin_dir_map_data, flags), 165745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org MAP_BRIEF|MAP_SECTIONS|MAP_SYMBOLS }, 165845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "brief", 0, yasm_dir_helper_flag_or, 165945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct bin_dir_map_data, flags), MAP_BRIEF }, 166045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "sections", 0, yasm_dir_helper_flag_or, 166145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct bin_dir_map_data, flags), MAP_SECTIONS }, 166245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "segments", 0, yasm_dir_helper_flag_or, 166345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct bin_dir_map_data, flags), MAP_SECTIONS }, 166445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "symbols", 0, yasm_dir_helper_flag_or, 166545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org offsetof(struct bin_dir_map_data, flags), MAP_SYMBOLS } 166645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org }; 166745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 166845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.flags = objfmt_bin->map_flags | MAP_NONE; 166945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org data.filename = objfmt_bin->map_filename; 167045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 167145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (valparams && yasm_dir_helper(object, yasm_vps_first(valparams), line, help, 167245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NELEMS(help), &data, dir_map_filename) < 0) 167345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; /* error occurred */ 167445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 167545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_bin->map_flags = data.flags; 167645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_bin->map_filename = data.filename; 167745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 167845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 167945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 168045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_section_data_destroy(void *data) 168145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 168245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_section_data *bsd = (bin_section_data *)data; 168345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bsd->start) 168445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_destroy(bsd->start); 168545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bsd->vstart) 168645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_destroy(bsd->vstart); 168745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bsd->follows) 168845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(bsd->follows); 168945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bsd->vfollows) 169045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(bsd->vfollows); 169145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bsd->istart) 169245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(bsd->istart); 169345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bsd->ivstart) 169445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(bsd->ivstart); 169545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bsd->length) 169645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_destroy(bsd->length); 169745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(data); 169845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 169945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 170045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 170145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_section_data_print(void *data, FILE *f, int indent_level) 170245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 170345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_section_data *bsd = (bin_section_data *)data; 170445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 170545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%*sbss=%d\n", indent_level, "", bsd->bss); 170645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 170745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%*salign=", indent_level, ""); 170845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bsd->align) 170945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_print(bsd->align, f); 171045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 171145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "(nil)"); 171245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n%*svalign=", indent_level, ""); 171345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bsd->valign) 171445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_print(bsd->valign, f); 171545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 171645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "(nil)"); 171745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 171845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n%*sstart=", indent_level, ""); 171945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_print(bsd->start, f); 172045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n%*svstart=", indent_level, ""); 172145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_print(bsd->vstart, f); 172245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 172345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n%*sfollows=", indent_level, ""); 172445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bsd->follows) 172545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\"%s\"", bsd->follows); 172645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 172745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "(nil)"); 172845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n%*svfollows=", indent_level, ""); 172945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bsd->vfollows) 173045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\"%s\"", bsd->vfollows); 173145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 173245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "(nil)"); 173345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 173445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n%*sistart=", indent_level, ""); 173545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bsd->istart) 173645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_print(bsd->istart, f); 173745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 173845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "(nil)"); 173945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n%*sivstart=", indent_level, ""); 174045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bsd->ivstart) 174145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_print(bsd->ivstart, f); 174245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 174345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "(nil)"); 174445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 174545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n%*slength=", indent_level, ""); 174645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bsd->length) 174745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum_print(bsd->length, f); 174845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 174945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "(nil)"); 175045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n"); 175145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 175245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 175345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 175445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_symrec_data_destroy(void *data) 175545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 175645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(data); 175745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 175845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 175945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 176045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbin_symrec_data_print(void *data, FILE *f, int indent_level) 176145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 176245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_symrec_data *bsymd = (bin_symrec_data *)data; 176345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 176445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%*ssection=\"%s\"\n", indent_level, "", 176545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_section_get_name(bsymd->section)); 176645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%*swhich=", indent_level, ""); 176745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (bsymd->which) { 176845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case SSYM_START: fprintf(f, "START"); break; 176945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case SSYM_VSTART: fprintf(f, "VSTART"); break; 177045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case SSYM_LENGTH: fprintf(f, "LENGTH"); break; 177145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 177245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "\n"); 177345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 177445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 177545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 177645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Define valid debug formats to use with this object format */ 177745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const char *bin_objfmt_dbgfmt_keywords[] = { 177845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "null", 177945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL 178045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 178145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 178245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const yasm_directive bin_objfmt_directives[] = { 178345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "org", "nasm", bin_objfmt_dir_org, YASM_DIR_ARG_REQUIRED }, 178445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "map", "nasm", bin_objfmt_dir_map, YASM_DIR_ANY }, 178545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { NULL, NULL, NULL, 0 } 178645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 178745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 178845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const char *bin_nasm_stdmac[] = { 178945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%imacro org 1+.nolist", 179045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "[org %1]", 179145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "%endmacro", 179245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL 179345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 179445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 179545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const yasm_stdmac bin_objfmt_stdmacs[] = { 179645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "nasm", "nasm", bin_nasm_stdmac }, 179745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "tasm", "tasm", bin_nasm_stdmac }, 179845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { NULL, NULL, NULL } 179945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 180045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 180145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Define objfmt structure -- see objfmt.h for details */ 180245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_objfmt_module yasm_bin_LTX_objfmt = { 180345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "Flat format binary", 180445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "bin", 180545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL, 180645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 16, 180745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 0, 180845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_dbgfmt_keywords, 180945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "null", 181045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_directives, 181145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_stdmacs, 181245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_create, 181345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_output, 181445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_destroy, 181545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_add_default_section, 1816a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org bin_objfmt_init_new_section, 181745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_section_switch, 181845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_get_special_sym 181945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 182045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 182145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define EXE_HEADER_SIZE 0x200 182245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 182345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* DOS .EXE binaries are just raw binaries with a header */ 182445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_objfmt_module yasm_dosexe_LTX_objfmt; 182545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 182645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_objfmt * 182745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgdosexe_objfmt_create(yasm_object *object) 182845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 182945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *) bin_objfmt_create(object); 183045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org objfmt_bin->objfmt.module = &yasm_dosexe_LTX_objfmt; 183145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return (yasm_objfmt *)objfmt_bin; 183245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 183345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 183445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic unsigned long 183545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgget_sym(yasm_object *object, const char *name) { 183645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec *symrec = yasm_symtab_get(object->symtab, name); 183745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_bytecode *prevbc; 183845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!symrec) 183945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 184045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!yasm_symrec_get_label(symrec, &prevbc)) 184145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 184245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return prevbc->offset + prevbc->len; 184345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 184445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 184545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 184645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgdosexe_objfmt_output(yasm_object *object, FILE *f, /*@unused@*/ int all_syms, 184745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_errwarns *errwarns) 184845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 184945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long tot_size, size, bss_size; 185045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long start, bss; 185145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned char c; 185245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 185345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fseek(f, EXE_HEADER_SIZE, SEEK_SET); 185445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 185545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_output(object, f, all_syms, errwarns); 185645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 185745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tot_size = ftell(f); 185845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 185945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* if there is a __bss_start symbol, data after it is 0, no need to write 186045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * it. */ 186145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bss = get_sym(object, "__bss_start"); 186245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (bss) 186345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size = bss; 186445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 186545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size = tot_size; 186645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bss_size = tot_size - size; 186745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifdef HAVE_FTRUNCATE 186845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (size != tot_size) 186945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ftruncate(fileno(f), EXE_HEADER_SIZE + size); 187045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 187145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fseek(f, 0, SEEK_SET); 187245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 187345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* magic */ 187445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite("MZ", 1, 2, f); 187545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 187645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* file size */ 187745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = size & 0xff; 187845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 187945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = !!(size & 0x100); 188045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 188145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = ((size + 511) >> 9) & 0xff; 188245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 188345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = ((size + 511) >> 17) & 0xff; 188445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 188545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 188645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* relocation # */ 188745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = 0; 188845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 188945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 189045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 189145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* header size */ 189245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = EXE_HEADER_SIZE / 16; 189345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 189445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = 0; 189545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 189645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 189745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* minimum paragraph # */ 189845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bss_size = (bss_size + 15) >> 4; 189945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = bss_size & 0xff; 190045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 190145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = (bss_size >> 8) & 0xff; 190245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 190345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 190445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* maximum paragraph # */ 190545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = 0xFF; 190645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 190745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 190845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 190945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* relative value of stack segment */ 191045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = 0; 191145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 191245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 191345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 191445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* SP at start */ 191545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = 0; 191645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 191745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 191845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 191945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* header checksum */ 192045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = 0; 192145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 192245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 192345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 192445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* IP at start */ 192545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org start = get_sym(object, "start"); 192645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!start) { 192745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_GENERAL, 192845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("%s: could not find symbol `start'")); 192945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return; 193045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 193145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = start & 0xff; 193245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 193345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = (start >> 8) & 0xff; 193445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 193545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 193645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* CS start */ 193745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = 0; 193845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 193945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 194045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 194145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* reloc start */ 194245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = 0x22; 194345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 194445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = 0; 194545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 194645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 194745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Overlay number */ 194845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org c = 0; 194945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 195045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fwrite(&c, 1, 1, f); 195145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 195245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 195345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 195445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Define objfmt structure -- see objfmt.h for details */ 195545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_objfmt_module yasm_dosexe_LTX_objfmt = { 195645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "DOS .EXE format binary", 195745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "dosexe", 195845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "exe", 195945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 16, 196045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 0, 196145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_dbgfmt_keywords, 196245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "null", 196345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_directives, 196445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_stdmacs, 196545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dosexe_objfmt_create, 196645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org dosexe_objfmt_output, 196745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_destroy, 196845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_add_default_section, 1969a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org bin_objfmt_init_new_section, 197045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_section_switch, 197145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org bin_objfmt_get_special_sym 197245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 1973