From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail From: Paul Rubin Newsgroups: comp.lang.ada Subject: Re: AI12-0218: What is the portable representation clause for processing IETF packets on little-endian machines? Date: Thu, 10 May 2018 18:34:41 -0700 Organization: A noiseless patient Spider Message-ID: <87wowbx9e6.fsf@nightsong.com> References: <9af47760-e731-4cb5-a1a0-d63e31019ce5@googlegroups.com> <877eob1cc6.fsf@nightsong.com> <87po23yusb.fsf@nightsong.com> <87603vyqxc.fsf@nightsong.com> <38ef3024-cc04-43bf-991f-7569eae82f45@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: reader02.eternal-september.org; posting-host="eb6deaf5ebc236909956e29d21385fdd"; logging-data="8349"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/KbZLnHVHyjyRCVstuA/1M" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) Cancel-Lock: sha1:9jXOtv1hWIVEd+vPEsx+epVtTQY= sha1:Ti8caQhrZ5giykY3JpZdOc64oHo= Xref: reader02.eternal-september.org comp.lang.ada:52239 Date: 2018-05-10T18:34:41-07:00 List-Id: "Dan'l Miller" writes: >> … it's intended to specify actual memory layout. >> That is a poor way to handle network byte order … > How does specifying “actual memory layout“ not include the topic of > byte order? I don't think representation clauses in Ada try to specify byte order of integers. A 32-bit integer is treated as an opaque object. It is represented in memory as 4 bytes but in to the doc I looked at, the byte order wasn't specified. In C, the byte order is observable because you can take the address of a 32-bit integer, cast it into a char pointer, and then look at the 4 bytes one at a time. But I think in Ada, you aren't supposed to cast addresses like that. An int is an int and a byte is a byte. > Endianness is quite honestly the ultimate very first topic in an ISA's > definition of “actual memory layout” Yes, and if Ada programs are supposed to be portable they shouldn't care what the byte order is. You can convert network to native byte order portably, something like: uint32 n = byte0 << 24 | byte1 << 16 | byte2 << 8 | byte3; where byte0, byte1, byte2, and byte3 are the 4 bytes from the network packet, giving the integer in big-endian order. That should work regardless of the cpu endianness. But, if the cpu is already big-endian then you have done a bunch of arithmetic that could have been replaced with a no-op. So in practice you use a conditionally-compiled macro. > Btw, what is nonactual memory layout or actual nonmemory layout or > actual memory nonlayout? I just mean if you say "uint32 n = 123456789;" that normally means you want 4 bytes in memory holding the machine's representation of that integer in the machine's native byte order, whatever that order happens to be. In big-endian order the 4 bytes (starting from the lowest address) would be 07 5B CD 15, while in little-endian order they would be 15 CD 5B 07. You leave it up to the compiler to generate this layout machine-dependently, instead of specifying it yourself. By "specify the actual memory layout" I mean you hypothetically write something like "big_endian_32 n = 123456789;" and that means you want the 4 bytes in memory to be 07 5B CD 15 in that order, even if the machine is little-endian. That means if you want to increment n on a little-endian machine, you have to read it from memory, swap the bytes around, increment, swap around the bytes of the result, and write them back out to memory. Normally a network programmer wouldn't do that. They'd read the big-endian sequence 07 5B CD 15 from the network, convert it (using a macro) to the endianness of whatever machine they are running on, and store it in memory in the machine's native byte order. Then if they want to increment it, they just use an increment instruction with no byte swapping needed. Finally if they want to write it back out to the network, they convert it to network byte order before sending. I hope that helps.