8000 Alignment violation fix in emitbc by pfalcon · Pull Request #747 · micropython/micropython · GitHub
[go: up one dir, main page]

Skip to content

Alignment violation fix in emitbc #747

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

Merged
merged 2 commits into from
Jul 13, 2014
Merged

Conversation

pfalcon
Copy link
Contributor
@pfalcon pfalcon commented Jul 12, 2014

I caught this when running on armv5. There specifically alignment violation didn't cause any segfault, just using non-aligned word pointer masks 2 lowest bits. In this case, uint assignment to dummy_data actually overwrote ->pass. It was a bit of chore to debug ;-). And I wonder, if we have more such cases...

Paul Sokolovsky added 2 commits July 12, 2014 15:57
dummy_data field is accessed as uint value (e.g.
in emit_write_bytecode_byte_ptr), but is not aligned as such, which causes
bus errors or incorrect behavior on any arch requiring strictly aligned
data (ARM pre-v7, MIPS, etc, etc).
@pfalcon
Copy link
Contributor Author
pfalcon commented Jul 12, 2014

Apparently,

    pass_kind_t pass : 8;
    uint last_emit_was_return_value : 8;

should be moved to the very end of structure to preserve packed structure size.

@dpgeorge
Copy link
Member

Nice catch. But I would prefer not to rely on having dummy_data aligned to a machine word within the emit_t struct (eg on 64 bit is it still aligned to a machine word when you put it at the end?). Could put dummy_data at the very start of the struct, that would guarantee allignment. Or, make dummy_data have type mp_uint_t (wastes a few bytes). Or, have a function emit_get_cur_to_write_bytecode_aligned that duplicates emit_get_cur_to_write_bytecode but with an alignment argument (and handles dummy_data separately to real bytecode data).

@dhylands
Copy link
Contributor

Since its declared as an array of bytes, it's only guaranteed to have byte alignment.

You can use an anonymous union to force the alignment:

union {
    byte dummy_data[DUMMY_DATA_SIZE];
    uint alignment;
};

Here's my little test program:

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>

typedef struct {
    uint8_t a;
    union {
        uint8_t b[12];
        unsigned int c;
    };
} foo_t;

int main(int argc, char **argv) {
    printf("Offset of a = %lu\n", offsetof(foo_t, a));
    printf("Offset of b = %lu\n", offsetof(foo_t, b));
    printf("Offset of c = %lu\n", offsetof(foo_t, c));
    return 0;
}

and the output:

Offset of a = 0
Offset of b = 4
Offset of c = 4

@dpgeorge
Copy link
Member

A union, I like it.

@pfalcon
Copy link
Contributor Author
pfalcon commented Jul 13, 2014

(eg on 64 bit is it still aligned to a machine word when you put it at the end?). Could put dummy_data at the very start of the struct, that would guarantee allignment.

Well, magic is not in being put at the end, but in being put after word-sized field, that surely guarantees alignment. Putting at the beginning wastes good slot for it - the most accessed field should be there, because archs which don't have index+offset addressing will take more cycles to calc address of any other field. mp_uint_t for dummy_data is what first version of the patch did. All other solutions add complications/syntactic noise IMHO.

So, let me merge this as is, and please apply more changes if you think they're needed. I'd rather suggest what to do about "pass" and "last_emit_was_return_value". They naturally would be moved after dummy_data to get back to the original struct sizeof, but I didn't do that exactly of the concern that "pass" is a frequently-accessed field.

@pfalcon pfalcon merged commit 564e464 into micropython:master Jul 13, 2014
@dpgeorge
Copy link
Member

So, let me merge this as is,

Okay, no problem. Just note that uint is not machine word sized.

@pfalcon pfalcon deleted the align-fix branch January 4, 2015 00:50
tannewt added a commit to tannewt/circuitpython that referenced this pull request Apr 11, 2018
add storage.erase_filesystem() to erase and reformat CIRCUITPY
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0