Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Unified Diff: third_party/yasm/patched-yasm/modules/objfmts/coff/coff-objfmt.c

Issue 11364046: Update Yasm to 1.2.0 (Yasm Part 1/3) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/yasm/patched-yasm/modules/objfmts/coff/coff-objfmt.c
===================================================================
--- third_party/yasm/patched-yasm/modules/objfmts/coff/coff-objfmt.c (revision 165590)
+++ third_party/yasm/patched-yasm/modules/objfmts/coff/coff-objfmt.c (working copy)
@@ -26,7 +26,6 @@
*/
#include <util.h>
#include <time.h>
-/*@unused@*/ RCSID("$Id: coff-objfmt.c 2347 2010-08-01 17:31:12Z peter $");
#include <libyasm.h>
@@ -183,10 +182,15 @@
coff_symrec_data *filesym_data; /* Data for .file symbol */
+ /* data for .def/.endef and related directives */
+ coff_symrec_data *def_sym; /* symbol specified by .def */
+
/* data for win64 proc_frame and related directives */
unsigned long proc_frame; /* Line number of start of proc, or 0 */
unsigned long done_prolog; /* Line number of end of prologue, or 0 */
/*@null@*/ coff_unwind_info *unwind; /* Unwind info */
+
+ yasm_symrec *ssym_imagebase; /* ..imagebase symbol for win64 */
} yasm_objfmt_coff;
typedef struct coff_objfmt_output_info {
@@ -227,7 +231,7 @@
static int win32_sxdata_bc_calc_len
(yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
static int win32_sxdata_bc_tobytes
- (yasm_bytecode *bc, unsigned char **bufp, void *d,
+ (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
yasm_output_value_func output_value,
/*@null@*/ yasm_output_reloc_func output_reloc);
@@ -294,6 +298,7 @@
objfmt_coff->proc_frame = 0;
objfmt_coff->done_prolog = 0;
objfmt_coff->unwind = NULL;
+ objfmt_coff->ssym_imagebase = NULL;
return objfmt_coff;
}
@@ -380,6 +385,8 @@
objfmt_coff->objfmt.module = &yasm_win64_LTX_objfmt;
objfmt_coff->win32 = 1;
objfmt_coff->win64 = 1;
+ objfmt_coff->ssym_imagebase =
+ yasm_symtab_define_label(object->symtab, "..imagebase", NULL, 0, 0);
}
return (yasm_objfmt *)objfmt_coff;
}
@@ -487,14 +494,18 @@
/*@dependent@*/ /*@null@*/ yasm_symrec *sym = value->rel;
unsigned long addr;
coff_reloc *reloc;
+ int nobase = info->csd->flags2 & COFF_FLAG_NOBASE;
/* Sometimes we want the relocation to be generated against one
* symbol but the value generated correspond to a different symbol.
* This is done through (sym being referenced) WRT (sym used for
* reloc). Note both syms need to be in the same section!
*/
- if (value->wrt) {
+ if (value->wrt && value->wrt == objfmt_coff->ssym_imagebase)
+ nobase = 1;
+ else if (value->wrt) {
/*@dependent@*/ /*@null@*/ yasm_bytecode *rel_precbc, *wrt_precbc;
+
if (!yasm_symrec_get_label(sym, &rel_precbc)
|| !yasm_symrec_get_label(value->wrt, &wrt_precbc)) {
yasm_error_set(YASM_ERROR_TOO_COMPLEX,
@@ -569,8 +580,8 @@
intn_minus = bc->offset;
}
- if (value->seg_of || value->section_rel) {
- /* Segment or section-relative generation; zero value. */
+ if (value->seg_of) {
+ /* Segment generation; zero value. */
intn_val = 0;
intn_minus = 0;
}
@@ -642,13 +653,13 @@
yasm_internal_error(N_("coff objfmt: unrecognized machine"));
} else {
if (objfmt_coff->machine == COFF_MACHINE_I386) {
- if (info->csd->flags2 & COFF_FLAG_NOBASE)
+ if (nobase)
reloc->type = COFF_RELOC_I386_ADDR32NB;
else
reloc->type = COFF_RELOC_I386_ADDR32;
} else if (objfmt_coff->machine == COFF_MACHINE_AMD64) {
if (valsize == 32) {
- if (info->csd->flags2 & COFF_FLAG_NOBASE)
+ if (nobase)
reloc->type = COFF_RELOC_AMD64_ADDR32NB;
else
reloc->type = COFF_RELOC_AMD64_ADDR32;
@@ -1512,6 +1523,7 @@
} else if (objfmt_coff->win64 && strcmp(sectname, ".xdata") == 0) {
data.flags = COFF_STYP_DATA | COFF_STYP_READ;
align = 8;
+ data.flags2 = COFF_FLAG_NOBASE;
} else if (objfmt_coff->win32 && strcmp(sectname, ".sxdata") == 0) {
data.flags = COFF_STYP_INFO;
} else if (strcmp(sectname, ".comment") == 0) {
@@ -1594,6 +1606,17 @@
return NULL;
}
+static /*@observer@*/ /*@null@*/ yasm_symrec *
+win64_objfmt_get_special_sym(yasm_object *object, const char *name,
+ const char *parser)
+{
+ if (yasm__strcasecmp(name, "imagebase") == 0) {
+ yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
+ return objfmt_coff->ssym_imagebase;
+ }
+ return NULL;
+}
+
static void
coff_section_data_destroy(void *data)
{
@@ -1758,7 +1781,8 @@
}
static int
-win32_sxdata_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+win32_sxdata_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
+ unsigned char *bufstart, void *d,
yasm_output_value_func output_value,
yasm_output_reloc_func output_reloc)
{
@@ -1840,6 +1864,131 @@
}
static void
+dir_secrel32(yasm_object *object, yasm_valparamhead *valparams,
+ yasm_valparamhead *objext_valparams, unsigned long line)
+{
+ yasm_datavalhead dvs;
+ yasm_valparam *vp;
+
+ if (!object->cur_section) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_(".secrel32 can only be used inside of a section"));
+ return;
+ }
+
+ vp = yasm_vps_first(valparams);
+ yasm_dvs_initialize(&dvs);
+ do {
+ yasm_expr *e = yasm_vp_expr(vp, object->symtab, line);
+ yasm_dataval *dv;
+ if (!e) {
+ yasm_error_set(YASM_ERROR_VALUE,
+ N_(".secrel32 requires expressions"));
+ yasm_dvs_delete(&dvs);
+ return;
+ }
+ dv = yasm_dv_create_expr(e);
+ yasm_dv_get_value(dv)->section_rel = 1;
+ yasm_dvs_append(&dvs, dv);
+ } while ((vp = yasm_vps_next(vp)));
+
+ yasm_section_bcs_append(object->cur_section,
+ yasm_bc_create_data(&dvs, 4, 0, object->arch, line));
+}
+
+static void
+dir_def(yasm_object *object, yasm_valparamhead *valparams,
+ yasm_valparamhead *objext_valparams, unsigned long line)
+{
+ yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
+ yasm_valparam *vp;
+ const char *symname;
+ yasm_symrec *sym;
+ coff_symrec_data *sym_data;
+
+ if (objfmt_coff->def_sym) {
+ yasm_warn_set(YASM_WARN_GENERAL,
+ N_(".def pseudo-op used inside of .def/.endef; ignored"));
+ return;
+ }
+
+ vp = yasm_vps_first(valparams);
+ symname = yasm_vp_id(vp);
+ if (!symname) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("argument to SAFESEH must be symbol name"));
+ return;
+ }
+
+ sym = yasm_symtab_use(object->symtab, symname, line);
+ sym_data = yasm_symrec_get_data(sym, &coff_symrec_data_cb);
+ if (!sym_data) {
+ sym_data = coff_objfmt_sym_set_data(sym, COFF_SCL_NULL, 0,
+ COFF_SYMTAB_AUX_NONE);
+ }
+ objfmt_coff->def_sym = sym_data;
+}
+
+static void
+dir_scl(yasm_object *object, yasm_valparamhead *valparams,
+ yasm_valparamhead *objext_valparams, unsigned long line)
+{
+ yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
+ yasm_intnum *intn = NULL;
+
+ if (!objfmt_coff->def_sym) {
+ yasm_warn_set(YASM_WARN_GENERAL,
+ N_("%s pseudo-op used outside of .def/.endef; ignored"),
+ ".scl");
+ return;
+ }
+
+ if (yasm_dir_helper_intn(object, yasm_vps_first(valparams), line,
+ &intn, 0) < 0)
+ return;
+ if (!intn)
+ return;
+ objfmt_coff->def_sym->sclass = yasm_intnum_get_uint(intn);
+ yasm_intnum_destroy(intn);
+}
+
+static void
+dir_type(yasm_object *object, yasm_valparamhead *valparams,
+ yasm_valparamhead *objext_valparams, unsigned long line)
+{
+ yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
+ yasm_intnum *intn = NULL;
+
+ if (!objfmt_coff->def_sym) {
+ yasm_warn_set(YASM_WARN_GENERAL,
+ N_("%s pseudo-op used outside of .def/.endef; ignored"),
+ ".type");
+ return;
+ }
+
+ if (yasm_dir_helper_intn(object, yasm_vps_first(valparams), line,
+ &intn, 0) < 0)
+ return;
+ if (!intn)
+ return;
+ objfmt_coff->def_sym->type = yasm_intnum_get_uint(intn);
+ yasm_intnum_destroy(intn);
+}
+
+static void
+dir_endef(yasm_object *object, yasm_valparamhead *valparams,
+ yasm_valparamhead *objext_valparams, unsigned long line)
+{
+ yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
+ if (!objfmt_coff->def_sym) {
+ yasm_warn_set(YASM_WARN_GENERAL,
+ N_(".endef pseudo-op used before .def; ignored"));
+ return;
+ }
+ objfmt_coff->def_sym = NULL;
+}
+
+static void
dir_proc_frame(yasm_object *object, /*@null@*/ yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
@@ -2194,6 +2343,11 @@
static const yasm_directive coff_objfmt_directives[] = {
{ ".ident", "gas", dir_ident, YASM_DIR_ANY },
{ "ident", "nasm", dir_ident, YASM_DIR_ANY },
+ { ".def", "gas", dir_def, YASM_DIR_ID_REQUIRED },
+ { ".endef", "gas", dir_endef, YASM_DIR_ANY },
+ { ".scl", "gas", dir_scl, YASM_DIR_ARG_REQUIRED },
+ { ".type", "gas", dir_type, YASM_DIR_ARG_REQUIRED },
+ { ".secrel32", "gas", dir_secrel32, YASM_DIR_ARG_REQUIRED },
{ NULL, NULL, NULL, 0 }
};
@@ -2228,6 +2382,11 @@
static const yasm_directive win32_objfmt_directives[] = {
{ ".ident", "gas", dir_ident, YASM_DIR_ANY },
{ "ident", "nasm", dir_ident, YASM_DIR_ANY },
+ { ".def", "gas", dir_def, YASM_DIR_ID_REQUIRED },
+ { ".endef", "gas", dir_endef, YASM_DIR_ANY },
+ { ".scl", "gas", dir_scl, YASM_DIR_ARG_REQUIRED },
+ { ".type", "gas", dir_type, YASM_DIR_ARG_REQUIRED },
+ { ".secrel32", "gas", dir_secrel32, YASM_DIR_ARG_REQUIRED },
{ ".export", "gas", dir_export, YASM_DIR_ID_REQUIRED },
{ "export", "nasm", dir_export, YASM_DIR_ID_REQUIRED },
{ ".safeseh", "gas", dir_safeseh, YASM_DIR_ID_REQUIRED },
@@ -2273,6 +2432,11 @@
static const yasm_directive win64_objfmt_directives[] = {
{ ".ident", "gas", dir_ident, YASM_DIR_ANY },
{ "ident", "nasm", dir_ident, YASM_DIR_ANY },
+ { ".def", "gas", dir_def, YASM_DIR_ID_REQUIRED },
+ { ".endef", "gas", dir_endef, YASM_DIR_ANY },
+ { ".scl", "gas", dir_scl, YASM_DIR_ARG_REQUIRED },
+ { ".type", "gas", dir_type, YASM_DIR_ARG_REQUIRED },
+ { ".secrel32", "gas", dir_secrel32, YASM_DIR_ARG_REQUIRED },
{ ".export", "gas", dir_export, YASM_DIR_ID_REQUIRED },
{ "export", "nasm", dir_export, YASM_DIR_ID_REQUIRED },
{ ".proc_frame", "gas", dir_proc_frame, YASM_DIR_ID_REQUIRED },
@@ -2322,7 +2486,7 @@
coff_objfmt_add_default_section,
coff_objfmt_init_new_section,
coff_objfmt_section_switch,
- coff_objfmt_get_special_sym
+ win64_objfmt_get_special_sym
};
yasm_objfmt_module yasm_x64_LTX_objfmt = {
"Win64",
@@ -2340,5 +2504,5 @@
coff_objfmt_add_default_section,
coff_objfmt_init_new_section,
coff_objfmt_section_switch,
- coff_objfmt_get_special_sym
+ win64_objfmt_get_special_sym
};

Powered by Google App Engine
This is Rietveld 408576698