Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mbr] Return -1 if relative index is not in given generation #49795

Merged
merged 1 commit into from
Mar 18, 2021

Conversation

lambdageek
Copy link
Member

@lambdageek lambdageek commented Mar 18, 2021

Logically after an update is applied, tokens refer to rows in tables that are a concatenation of all the added rows from every update. (ie: if the baseline table 0x23 had 2 rows and then generation 1 an added 3 more rows, an index like 0x05
refers to table 0x23 row 3 from gen 1).

The way the lookup works is that the EnC map table records the logical tokens of the update. So for table 0x23 the 3 additions in gen 1 will have entries like encmap row 5 = 0x23000003, row 6 = 0x23000004, row 7 = 0x23000005, and then rows for the next table and so on. The relative index in gen1 of token 0x23000005 then, is the distance of its row (ie row 7) from the first token for the table (ie row 5), plus 1 (since tokens are 1-based). So in this case token 0x23000005 corresponds to the 7-5+1 = 3rd row of table 0x23 in the gen1 dmeta image.

The problem is that previously we returns this index-base+1 computation even in cases where we walked either to the end of the encmap table or past the last row for the table we care about.

In the case where we walked to the end of the encmap table, the index-base+1 could sometimes return a value that looked like a valid token. The upshot is that we looked up an incorrect AssemblyRef (0x23 table) from the wrong generation.

The updated code returns -1 for all cases where we didn't find an encmap row for our given token.

Example: https://gist.github.com/lambdageek/cd7ea06bf5004ba884e7979f28623da5

Contributes to #44806

Logically after an update is applied, tokens refer to rows in tables that are a
concatenation of all the added rows from every update.  (ie: if the baseline
table 0x23 had 2 rows and then generation 1 an added 3 more rows, an index like 0x05
refers to table 0x23 row 3 from gen 1).

The way the lookup works is that the EnC map table records the logical tokens
of the update.  So for table 0x23 the 3 additions in gen 1 will have entries
like encmap row 5 = 0x23000003, row 6 = 0x23000004, row 7 = 0x23000005, and
then rows for the next table and so on.  The relative index in gen1 of token
0x23000005 then, is the distance of its row (ie row 7) from the first token for
the table (ie row 5), plus 1 (since tokens are 1-based).  So in this case token
0x23000005 corresponds to the 7-5+1 = 3rd row of table 0x23 in the gen1 dmeta image.

The problem is that previously we returns this index-base+1 computation even in
cases where we walked either to the end of the encmap table or past the last
row for the table we care about.

In the case where we walked to the end of the encmap table, the index-base+1
could sometimes return a value that looked like a valid token.  The upshot is
that we looked up an incorrect AssemblyRef (0x23 table) from the wrong
generation.

The updated code returns -1 for all cases where we didn't find an encmap row
for our given token.

Example: https://gist.github.com/lambdageek/cd7ea06bf5004ba884e7979f28623da5
@ghost
Copy link

ghost commented Mar 18, 2021

Tagging subscribers to this area: @CoffeeFlux
See info in area-owners.md if you want to be subscribed.

Issue Details

Logically after an update is applied, tokens refer to rows in tables that are a concatenation of all the added rows from every update. (ie: if the baseline table 0x23 had 2 rows and then generation 1 an added 3 more rows, an index like 0x05
refers to table 0x23 row 3 from gen 1).

The way the lookup works is that the EnC map table records the logical tokens of the update. So for table 0x23 the 3 additions in gen 1 will have entries like encmap row 5 = 0x23000003, row 6 = 0x23000004, row 7 = 0x23000005, and then rows for the next table and so on. The relative index in gen1 of token 0x23000005 then, is the distance of its row (ie row 7) from the first token for the table (ie row 5), plus 1 (since tokens are 1-based). So in this case token 0x23000005 corresponds to the 7-5+1 = 3rd row of table 0x23 in the gen1 dmeta image.

The problem is that previously we returns this index-base+1 computation even in cases where we walked either to the end of the encmap table or past the last row for the table we care about.

In the case where we walked to the end of the encmap table, the index-base+1 could sometimes return a value that looked like a valid token. The upshot is that we looked up an incorrect AssemblyRef (0x23 table) from the wrong generation.

The updated code returns -1 for all cases where we didn't find an encmap row for our given token.

Example: https://gist.github.com/lambdageek/cd7ea06bf5004ba884e7979f28623da5

Author: lambdageek
Assignees: -
Labels:

area-VM-meta-mono

Milestone: -

@lambdageek
Copy link
Member Author

/cc @pranavkm this should fix the weird component issue

@lambdageek lambdageek mentioned this pull request Mar 18, 2021
51 tasks
@pranavkm
Copy link
Contributor

Looks like this is good to merge.

@lambdageek lambdageek merged commit 009c978 into dotnet:main Mar 18, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Apr 17, 2021
@karelz karelz added this to the 6.0.0 milestone May 20, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants