Skip to content

Commit

Permalink
[metadata] Don't access MonoTableInfo:rows, use table_info_get_rows() (
Browse files Browse the repository at this point in the history
…#49738)

Rename the field to `rows_`.

Also updated some bounds checks to use `mono_metadata_table_bounds_check` (which is metadata-update aware) where the subsequent lookups go through the metadata decode functions and should just work with metadata-update.

Added `FIXME: metadata-update` in cases where the table row size is assumed to be
fixed or is used as a sentinel value, or where the decoding may depend on
sorting properties that metadata updates probably won't uphold.
  • Loading branch information
lambdageek authored Mar 23, 2021
1 parent bc82161 commit dc5c909
Show file tree
Hide file tree
Showing 17 changed files with 338 additions and 222 deletions.
12 changes: 7 additions & 5 deletions src/mono/mono/metadata/assembly.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ mono_assembly_fill_assembly_name_full (MonoImage *image, MonoAssemblyName *aname
guint32 cols [MONO_ASSEMBLY_SIZE];
gint32 machine, flags;

if (!t->rows)
if (!table_info_get_rows (t))
return FALSE;

mono_metadata_decode_row (t, 0, cols, MONO_ASSEMBLY_SIZE);
Expand Down Expand Up @@ -1237,8 +1237,9 @@ mono_assembly_load_reference (MonoImage *image, int index)
if (!image->references) {
MonoTableInfo *t = &image->tables [MONO_TABLE_ASSEMBLYREF];

image->references = g_new0 (MonoAssembly *, t->rows + 1);
image->nreferences = t->rows;
int n = table_info_get_rows (t);
image->references = g_new0 (MonoAssembly *, n + 1);
image->nreferences = n;
}
reference = image->references [index];
mono_image_unlock (image);
Expand Down Expand Up @@ -2334,7 +2335,7 @@ mono_assembly_request_load_from (MonoImage *image, const char *fname,
predicate = req->predicate;
user_data = req->predicate_ud;

if (!image->tables [MONO_TABLE_ASSEMBLY].rows) {
if (!table_info_get_rows (&image->tables [MONO_TABLE_ASSEMBLY])) {
/* 'image' doesn't have a manifest -- maybe someone is trying to Assembly.Load a .netmodule */
*status = MONO_IMAGE_IMAGE_INVALID;
return NULL;
Expand Down Expand Up @@ -3685,7 +3686,8 @@ mono_assembly_has_skip_verification (MonoAssembly *assembly)

t = &assembly->image->tables [MONO_TABLE_DECLSECURITY];

for (i = 0; i < t->rows; ++i) {
int rows = table_info_get_rows (t);
for (i = 0; i < rows; ++i) {
mono_metadata_decode_row (t, i, cols, MONO_DECL_SECURITY_SIZE);
if ((cols [MONO_DECL_SECURITY_PARENT] & MONO_HAS_DECL_SECURITY_MASK) != MONO_HAS_DECL_SECURITY_ASSEMBLY)
continue;
Expand Down
13 changes: 7 additions & 6 deletions src/mono/mono/metadata/class-init.c
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,8 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError

error_init (error);

if (mono_metadata_token_table (type_token) != MONO_TABLE_TYPEDEF || tidx > tt->rows) {
/* FIXME: metadata-update - this function needs extensive work */
if (mono_metadata_token_table (type_token) != MONO_TABLE_TYPEDEF || tidx > table_info_get_rows (tt)) {
mono_error_set_bad_image (error, image, "Invalid typedef token %x", type_token);
return NULL;
}
Expand Down Expand Up @@ -620,19 +621,19 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError
first_method_idx = cols [MONO_TYPEDEF_METHOD_LIST] - 1;
mono_class_set_first_method_idx (klass, first_method_idx);

if (tt->rows > tidx){
if (table_info_get_rows (tt) > tidx){
mono_metadata_decode_row (tt, tidx, cols_next, MONO_TYPEDEF_SIZE);
field_last = cols_next [MONO_TYPEDEF_FIELD_LIST] - 1;
method_last = cols_next [MONO_TYPEDEF_METHOD_LIST] - 1;
} else {
field_last = image->tables [MONO_TABLE_FIELD].rows;
method_last = image->tables [MONO_TABLE_METHOD].rows;
field_last = table_info_get_rows (&image->tables [MONO_TABLE_FIELD]);
method_last = table_info_get_rows (&image->tables [MONO_TABLE_METHOD]);
}

if (cols [MONO_TYPEDEF_FIELD_LIST] &&
cols [MONO_TYPEDEF_FIELD_LIST] <= image->tables [MONO_TABLE_FIELD].rows)
cols [MONO_TYPEDEF_FIELD_LIST] <= table_info_get_rows (&image->tables [MONO_TABLE_FIELD]))
mono_class_set_field_count (klass, field_last - first_field_idx);
if (cols [MONO_TYPEDEF_METHOD_LIST] <= image->tables [MONO_TABLE_METHOD].rows)
if (cols [MONO_TYPEDEF_METHOD_LIST] <= table_info_get_rows (&image->tables [MONO_TABLE_METHOD]))
mono_class_set_method_count (klass, method_last - first_method_idx);

/* reserve space to store vector pointer in arrays */
Expand Down
28 changes: 17 additions & 11 deletions src/mono/mono/metadata/class.c
Original file line number Diff line number Diff line change
Expand Up @@ -2678,13 +2678,14 @@ mono_class_name_from_token (MonoImage *image, guint32 type_token)

switch (type_token & 0xff000000){
case MONO_TOKEN_TYPE_DEF: {
guint32 cols [MONO_TYPEDEF_SIZE];
MonoTableInfo *tt = &image->tables [MONO_TABLE_TYPEDEF];
guint tidx = mono_metadata_token_index (type_token);

if (tidx > tt->rows)
if (mono_metadata_table_bounds_check (image, MONO_TABLE_TYPEDEF, tidx))
return g_strdup_printf ("Invalid type token 0x%08x", type_token);

guint32 cols [MONO_TYPEDEF_SIZE];
MonoTableInfo *tt = &image->tables [MONO_TABLE_TYPEDEF];

mono_metadata_decode_row (tt, tidx - 1, cols, MONO_TYPEDEF_SIZE);
name = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAME]);
nspace = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAMESPACE]);
Expand All @@ -2695,13 +2696,14 @@ mono_class_name_from_token (MonoImage *image, guint32 type_token)
}

case MONO_TOKEN_TYPE_REF: {
guint32 cols [MONO_TYPEREF_SIZE];
MonoTableInfo *t = &image->tables [MONO_TABLE_TYPEREF];
guint tidx = mono_metadata_token_index (type_token);

if (tidx > t->rows)
if (mono_metadata_table_bounds_check (image, MONO_TABLE_TYPEREF, tidx))
return g_strdup_printf ("Invalid type token 0x%08x", type_token);

guint32 cols [MONO_TYPEREF_SIZE];
MonoTableInfo *t = &image->tables [MONO_TABLE_TYPEREF];

mono_metadata_decode_row (t, tidx-1, cols, MONO_TYPEREF_SIZE);
name = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAME]);
nspace = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAMESPACE]);
Expand Down Expand Up @@ -2738,7 +2740,7 @@ mono_assembly_name_from_token (MonoImage *image, guint32 type_token)
MonoTableInfo *t = &image->tables [MONO_TABLE_TYPEREF];
guint32 idx = mono_metadata_token_index (type_token);

if (idx > t->rows)
if (mono_metadata_table_bounds_check (image, MONO_TABLE_TYPEREF, idx))
return g_strdup_printf ("Invalid type token 0x%08x", type_token);

mono_metadata_decode_row (t, idx-1, cols, MONO_TYPEREF_SIZE);
Expand Down Expand Up @@ -2973,7 +2975,9 @@ mono_image_init_name_cache (MonoImage *image)
/* Temporary hash table to avoid lookups in the nspace_table */
name_cache2 = g_hash_table_new (NULL, NULL);

for (i = 1; i <= t->rows; ++i) {
/* FIXME: metadata-update */
int rows = table_info_get_rows (t);
for (i = 1; i <= rows; ++i) {
mono_metadata_decode_row (t, i - 1, cols, MONO_TYPEDEF_SIZE);
visib = cols [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_VISIBILITY_MASK;
/*
Expand Down Expand Up @@ -3002,7 +3006,8 @@ mono_image_init_name_cache (MonoImage *image)
guint32 cols [MONO_EXP_TYPE_SIZE];
int i;

for (i = 0; i < t->rows; ++i) {
rows = table_info_get_rows (t);
for (i = 0; i < rows; ++i) {
mono_metadata_decode_row (t, i, cols, MONO_EXP_TYPE_SIZE);

guint32 impl = cols [MONO_EXP_TYPE_IMPLEMENTATION];
Expand Down Expand Up @@ -3191,7 +3196,8 @@ search_modules (MonoImage *image, const char *name_space, const char *name, gboo
* Note: image->modules contains the contents of the MODULEREF table, while
* the real module list is in the FILE table.
*/
for (i = 0; i < file_table->rows; i++) {
int rows = table_info_get_rows (file_table);
for (i = 0; i < rows; i++) {
guint32 cols [MONO_FILE_SIZE];
mono_metadata_decode_row (file_table, i, cols, MONO_FILE_SIZE);
if (cols [MONO_FILE_FLAGS] == FILE_CONTAINS_NO_METADATA)
Expand Down Expand Up @@ -3244,7 +3250,7 @@ mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, cons

/* FIXME: get_class_from_name () can't handle types in the EXPORTEDTYPE table */
// The AOT cache in get_class_from_name is case-sensitive, so don't bother with it for case-insensitive lookups
if (get_class_from_name && image->tables [MONO_TABLE_EXPORTEDTYPE].rows == 0 && case_sensitive) {
if (get_class_from_name && table_info_get_rows (&image->tables [MONO_TABLE_EXPORTEDTYPE]) == 0 && case_sensitive) {
gboolean res = get_class_from_name (image, name_space, name, &klass);
if (res) {
if (!klass) {
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/metadata/coree.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ BOOL STDMETHODCALLTYPE _CorDllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpRes
* loader trampolines should be used and assembly loading should
* probably be delayed until the first call to an exported function.
*/
if (image->tables [MONO_TABLE_ASSEMBLY].rows && image->image_info->cli_cli_header.ch_vtable_fixups.rva) {
if (table_info_get_rows (&image->tables [MONO_TABLE_ASSEMBLY]) && image->image_info->cli_cli_header.ch_vtable_fixups.rva) {
MonoAssemblyOpenRequest req;
mono_assembly_request_prepare_open (&req, MONO_ASMCTX_DEFAULT, alc);
assembly = mono_assembly_request_open (file_name, &req, NULL);
Expand Down
33 changes: 22 additions & 11 deletions src/mono/mono/metadata/custom-attrs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1623,14 +1623,16 @@ mono_custom_attrs_from_index_checked (MonoImage *image, guint32 idx, gboolean ig
error_init (error);

ca = &image->tables [MONO_TABLE_CUSTOMATTRIBUTE];
/* FIXME: metadata-update */
int rows = table_info_get_rows (ca);

i = mono_metadata_custom_attrs_from_index (image, idx);
if (!i)
return NULL;
i --;
// initial size chosen arbitrarily, but default is 16 which is rather small
attr_array = g_array_sized_new (TRUE, TRUE, sizeof (guint32), 128);
while (i < ca->rows) {
while (i < rows) {
if (mono_metadata_decode_row_col (ca, i, MONO_CUSTOM_ATTR_PARENT) != idx)
break;
attr_array = g_array_append_val (attr_array, i);
Expand Down Expand Up @@ -1978,14 +1980,16 @@ mono_custom_attrs_from_param_checked (MonoMethod *method, guint32 param, MonoErr
return NULL;
ca = &image->tables [MONO_TABLE_METHOD];

/* FIXME: metadata-update */
param_list = mono_metadata_decode_row_col (ca, method_index - 1, MONO_METHOD_PARAMLIST);
if (method_index == ca->rows) {
ca = &image->tables [MONO_TABLE_PARAM];
param_last = ca->rows + 1;
int rows = table_info_get_rows (ca);
if (method_index == rows) {
param_last = rows + 1;
} else {
param_last = mono_metadata_decode_row_col (ca, method_index, MONO_METHOD_PARAMLIST);
ca = &image->tables [MONO_TABLE_PARAM];
}
ca = &image->tables [MONO_TABLE_PARAM];

found = FALSE;
for (i = param_list; i < param_last; ++i) {
param_pos = mono_metadata_decode_row_col (ca, i - 1, MONO_PARAM_SEQUENCE);
Expand Down Expand Up @@ -2345,7 +2349,7 @@ custom_attr_class_name_from_methoddef (MonoImage *image, guint32 method_token, c
guint32 cols [MONO_TYPEDEF_SIZE];
guint tidx = mono_metadata_token_index (type_token);

if (mono_metadata_token_table (type_token) != MONO_TABLE_TYPEDEF || tidx > tt->rows) {
if (mono_metadata_token_table (type_token) != MONO_TABLE_TYPEDEF || mono_metadata_table_bounds_check (image, MONO_TABLE_TYPEDEF, tidx)) {
/* "Invalid typedef token %x", type_token */
return FALSE;
}
Expand Down Expand Up @@ -2485,7 +2489,8 @@ metadata_foreach_custom_attr_from_index (MonoImage *image, guint32 idx, MonoAsse
return;
i --;
gboolean stop_iterating = FALSE;
while (!stop_iterating && i < ca->rows) {
int rows = table_info_get_rows (ca);
while (!stop_iterating && i < rows) {
if (mono_metadata_decode_row_col (ca, i, MONO_CUSTOM_ATTR_PARENT) != idx)
break;
mono_metadata_decode_row (ca, i, cols, MONO_CUSTOM_ATTR_SIZE);
Expand Down Expand Up @@ -2600,7 +2605,8 @@ init_weak_fields_inner (MonoImage *image, GHashTable *indexes)

tdef = &image->tables [MONO_TABLE_CUSTOMATTRIBUTE];
guint32 parent, field_idx, col, mtoken, idx;
for (int i = 0; i < tdef->rows; ++i) {
int rows = table_info_get_rows (tdef);
for (int i = 0; i < rows; ++i) {
parent = mono_metadata_decode_row_col (tdef, i, MONO_CUSTOM_ATTR_PARENT);
if ((parent & MONO_CUSTOM_ATTR_MASK) != MONO_CUSTOM_ATTR_FIELDDEF)
continue;
Expand All @@ -2616,13 +2622,16 @@ init_weak_fields_inner (MonoImage *image, GHashTable *indexes)
}
}
} else {
/* FIXME: metadata-update */

/* Memberref pointing to a typeref */
tdef = &image->tables [MONO_TABLE_MEMBERREF];

/* Check whenever the assembly references the WeakAttribute type */
gboolean found = FALSE;
tdef = &image->tables [MONO_TABLE_TYPEREF];
for (int i = 0; i < tdef->rows; ++i) {
int rows = table_info_get_rows (tdef);
for (int i = 0; i < rows; ++i) {
guint32 string_offset = mono_metadata_decode_row_col (tdef, i, MONO_TYPEREF_NAME);
const char *name = mono_metadata_string_heap (image, string_offset);
if (!strcmp (name, "WeakAttribute")) {
Expand All @@ -2636,7 +2645,8 @@ init_weak_fields_inner (MonoImage *image, GHashTable *indexes)

/* Find the memberref pointing to a typeref */
tdef = &image->tables [MONO_TABLE_MEMBERREF];
for (int i = 0; i < tdef->rows; ++i) {
rows = table_info_get_rows (tdef);
for (int i = 0; i < rows; ++i) {
guint32 cols [MONO_MEMBERREF_SIZE];
const char *sig;

Expand Down Expand Up @@ -2686,7 +2696,8 @@ init_weak_fields_inner (MonoImage *image, GHashTable *indexes)

tdef = &image->tables [MONO_TABLE_CUSTOMATTRIBUTE];
guint32 parent, field_idx, col, mtoken, idx;
for (int i = 0; i < tdef->rows; ++i) {
rows = table_info_get_rows (tdef);
for (int i = 0; i < rows; ++i) {
parent = mono_metadata_decode_row_col (tdef, i, MONO_CUSTOM_ATTR_PARENT);
if ((parent & MONO_CUSTOM_ATTR_MASK) != MONO_CUSTOM_ATTR_FIELDDEF)
continue;
Expand Down
24 changes: 13 additions & 11 deletions src/mono/mono/metadata/debug-mono-ppdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ mono_ppdb_load_file (MonoImage *image, const guint8 *raw_contents, int size)
int ppdb_size = 0, ppdb_compressed_size = 0;
gboolean is_embedded_ppdb = FALSE;

if (image->tables [MONO_TABLE_DOCUMENT].rows) {
if (table_info_get_rows (&image->tables [MONO_TABLE_DOCUMENT])) {
/* Embedded ppdb */
mono_image_addref (image);
return create_ppdb_file (image, TRUE);
Expand Down Expand Up @@ -490,16 +490,16 @@ mono_ppdb_get_seq_points (MonoDebugMethodInfo *minfo, char **source_file, GPtrAr
if (source_files)
sindexes = g_ptr_array_new ();

if (!method->token || tables [MONO_TABLE_METHODBODY].rows == 0)
if (!method->token || table_info_get_rows (&tables [MONO_TABLE_METHODBODY]) == 0)
return;

method_idx = mono_metadata_token_index (method->token);

MonoTableInfo *methodbody_table = &tables [MONO_TABLE_METHODBODY];
if (G_UNLIKELY (method_idx - 1 >= methodbody_table->rows)) {
if (G_UNLIKELY (method_idx - 1 >= table_info_get_rows (methodbody_table))) {
char *method_name = mono_method_full_name (method, FALSE);
g_error ("Method idx %d is greater than number of rows (%d) in PPDB MethodDebugInformation table, for method %s in '%s'. Likely a malformed PDB file.",
method_idx - 1, methodbody_table->rows, method_name, image->name);
method_idx - 1, table_info_get_rows (methodbody_table), method_name, image->name);
g_free (method_name);
}
mono_metadata_decode_row (methodbody_table, method_idx - 1, cols, MONO_METHODBODY_SIZE);
Expand Down Expand Up @@ -641,7 +641,8 @@ mono_ppdb_lookup_locals (MonoDebugMethodInfo *minfo)
// this endpoint becomes locals_end_idx below

// March to the last scope that is in this method
while (scope_idx <= tables [MONO_TABLE_LOCALSCOPE].rows) {
int rows = table_info_get_rows (&tables [MONO_TABLE_LOCALSCOPE]);
while (scope_idx <= rows) {
mono_metadata_decode_row (&tables [MONO_TABLE_LOCALSCOPE], scope_idx-1, cols, MONO_LOCALSCOPE_SIZE);
if (cols [MONO_LOCALSCOPE_METHOD] != method_idx)
break;
Expand All @@ -654,8 +655,8 @@ mono_ppdb_lookup_locals (MonoDebugMethodInfo *minfo)
// Ends with "the last row of the LocalVariable table"
// this happens if the above loop marched one past the end
// of the rows
if (scope_idx > tables [MONO_TABLE_LOCALSCOPE].rows) {
locals_end_idx = tables [MONO_TABLE_LOCALVARIABLE].rows + 1;
if (scope_idx > table_info_get_rows (&tables [MONO_TABLE_LOCALSCOPE])) {
locals_end_idx = table_info_get_rows (&tables [MONO_TABLE_LOCALVARIABLE]) + 1;
} else {
// Ends with "the next run of LocalVariables,
// found by inspecting the VariableList of the next row in this LocalScope table."
Expand All @@ -674,8 +675,8 @@ mono_ppdb_lookup_locals (MonoDebugMethodInfo *minfo)
mono_metadata_decode_row (&tables [MONO_TABLE_LOCALSCOPE], scope_idx-1, cols, MONO_LOCALSCOPE_SIZE);

locals_idx = cols [MONO_LOCALSCOPE_VARIABLELIST];
if (scope_idx == tables [MONO_TABLE_LOCALSCOPE].rows) {
locals_end_idx = tables [MONO_TABLE_LOCALVARIABLE].rows + 1;
if (scope_idx == table_info_get_rows (&tables [MONO_TABLE_LOCALSCOPE])) {
locals_end_idx = table_info_get_rows (&tables [MONO_TABLE_LOCALVARIABLE]) + 1;
} else {
locals_end_idx = mono_metadata_decode_row_col (&tables [MONO_TABLE_LOCALSCOPE], scope_idx-1 + 1, MONO_LOCALSCOPE_VARIABLELIST);
}
Expand Down Expand Up @@ -756,15 +757,16 @@ lookup_custom_debug_information (MonoImage* image, guint32 token, uint8_t parent
loc.col_idx = MONO_CUSTOMDEBUGINFORMATION_PARENT;
loc.t = table;

if (!mono_binary_search (&loc, table->base, table->rows, table->row_size, table_locator))
if (!mono_binary_search (&loc, table->base, table_info_get_rows (table), table->row_size, table_locator))
return NULL;
// Great we found one of possibly many CustomDebugInformations of this entity they are distinguished by KIND guid
// First try on this index found by binary search...(it's most likeley to be only one and binary search found the one we want)
if (compare_guid (guid, (guint8*)mono_metadata_guid_heap (image, mono_metadata_decode_row_col (table, loc.result, MONO_CUSTOMDEBUGINFORMATION_KIND))))
return mono_metadata_blob_heap (image, mono_metadata_decode_row_col (table, loc.result, MONO_CUSTOMDEBUGINFORMATION_VALUE));

// Move forward from binary found index, until parent token differs
for (int i = loc.result + 1; i < table->rows; i++)
int rows = table_info_get_rows (table);
for (int i = loc.result + 1; i < rows; i++)
{
if (mono_metadata_decode_row_col (table, i, MONO_CUSTOMDEBUGINFORMATION_PARENT) != loc.idx)
break;
Expand Down
Loading

0 comments on commit dc5c909

Please sign in to comment.