1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-09-22 13:45:21 +03:00

Merge pull request #7675 from shawnl/unaligned

Issue #7654 (unaligned loads on sparc64)
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2018-01-20 10:00:14 +11:00
committed by GitHub
3 changed files with 30 additions and 40 deletions

View File

@@ -26,89 +26,77 @@
/* BE */ /* BE */
static inline uint16_t unaligned_read_be16(const void *_u) { static inline uint16_t unaligned_read_be16(const void *_u) {
const uint8_t *u = _u; const struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u;
return (((uint16_t) u[0]) << 8) | return be16toh(u->x);
((uint16_t) u[1]);
} }
static inline uint32_t unaligned_read_be32(const void *_u) { static inline uint32_t unaligned_read_be32(const void *_u) {
const uint8_t *u = _u; const struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u;
return (((uint32_t) unaligned_read_be16(u)) << 16) | return be32toh(u->x);
((uint32_t) unaligned_read_be16(u + 2));
} }
static inline uint64_t unaligned_read_be64(const void *_u) { static inline uint64_t unaligned_read_be64(const void *_u) {
const uint8_t *u = _u; const struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u;
return (((uint64_t) unaligned_read_be32(u)) << 32) | return be64toh(u->x);
((uint64_t) unaligned_read_be32(u + 4));
} }
static inline void unaligned_write_be16(void *_u, uint16_t a) { static inline void unaligned_write_be16(void *_u, uint16_t a) {
uint8_t *u = _u; struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u;
u[0] = (uint8_t) (a >> 8); u->x = be16toh(a);
u[1] = (uint8_t) a;
} }
static inline void unaligned_write_be32(void *_u, uint32_t a) { static inline void unaligned_write_be32(void *_u, uint32_t a) {
uint8_t *u = _u; struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u;
unaligned_write_be16(u, (uint16_t) (a >> 16)); u->x = be32toh(a);
unaligned_write_be16(u + 2, (uint16_t) a);
} }
static inline void unaligned_write_be64(void *_u, uint64_t a) { static inline void unaligned_write_be64(void *_u, uint64_t a) {
uint8_t *u = _u; struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u;
unaligned_write_be32(u, (uint32_t) (a >> 32)); u->x = be64toh(a);
unaligned_write_be32(u + 4, (uint32_t) a);
} }
/* LE */ /* LE */
static inline uint16_t unaligned_read_le16(const void *_u) { static inline uint16_t unaligned_read_le16(const void *_u) {
const uint8_t *u = _u; const struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u;
return (((uint16_t) u[1]) << 8) | return le16toh(u->x);
((uint16_t) u[0]);
} }
static inline uint32_t unaligned_read_le32(const void *_u) { static inline uint32_t unaligned_read_le32(const void *_u) {
const uint8_t *u = _u; const struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u;
return (((uint32_t) unaligned_read_le16(u + 2)) << 16) | return le32toh(u->x);
((uint32_t) unaligned_read_le16(u));
} }
static inline uint64_t unaligned_read_le64(const void *_u) { static inline uint64_t unaligned_read_le64(const void *_u) {
const uint8_t *u = _u; const struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u;
return (((uint64_t) unaligned_read_le32(u + 4)) << 32) | return le64toh(u->x);
((uint64_t) unaligned_read_le32(u));
} }
static inline void unaligned_write_le16(void *_u, uint16_t a) { static inline void unaligned_write_le16(void *_u, uint16_t a) {
uint8_t *u = _u; struct __attribute__((packed, may_alias)) { uint16_t x; } *u = _u;
u[0] = (uint8_t) a; u->x = le16toh(a);
u[1] = (uint8_t) (a >> 8);
} }
static inline void unaligned_write_le32(void *_u, uint32_t a) { static inline void unaligned_write_le32(void *_u, uint32_t a) {
uint8_t *u = _u; struct __attribute__((packed, may_alias)) { uint32_t x; } *u = _u;
unaligned_write_le16(u, (uint16_t) a); u->x = le32toh(a);
unaligned_write_le16(u + 2, (uint16_t) (a >> 16));
} }
static inline void unaligned_write_le64(void *_u, uint64_t a) { static inline void unaligned_write_le64(void *_u, uint64_t a) {
uint8_t *u = _u; struct __attribute__((packed, may_alias)) { uint64_t x; } *u = _u;
unaligned_write_le32(u, (uint32_t) a); u->x = le64toh(a);
unaligned_write_le32(u + 4, (uint32_t) (a >> 32));
} }
#if __BYTE_ORDER == __BIG_ENDIAN #if __BYTE_ORDER == __BIG_ENDIAN

View File

@@ -24,6 +24,7 @@
#include "arp-util.h" #include "arp-util.h"
#include "fd-util.h" #include "fd-util.h"
#include "unaligned.h"
#include "util.h" #include "util.h"
int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_addr *eth_mac) { int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_addr *eth_mac) {
@@ -48,12 +49,12 @@ int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REPLY, 1, 0), /* protocol == reply ? */ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REPLY, 1, 0), /* protocol == reply ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
/* Sender Hardware Address must be different from our own */ /* Sender Hardware Address must be different from our own */
BPF_STMT(BPF_LD + BPF_IMM, htobe32(*((uint32_t *) eth_mac))), /* A <- 4 bytes of client's MAC */ BPF_STMT(BPF_LD + BPF_IMM, unaligned_read_ne32(&eth_mac->ether_addr_octet[0])),/* A <- 4 bytes of client's MAC */
BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */ BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ether_arp, arp_sha)), /* A <- 4 bytes of SHA */ BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ether_arp, arp_sha)), /* A <- 4 bytes of SHA */
BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */ BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 6), /* A == 0 ? */ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 6), /* A == 0 ? */
BPF_STMT(BPF_LD + BPF_IMM, htobe16(*((uint16_t *) (((char *) eth_mac) + 4)))), /* A <- remainder of client's MAC */ BPF_STMT(BPF_LD + BPF_IMM, unaligned_read_ne16(&eth_mac->ether_addr_octet[4])),/* A <- remainder of client's MAC */
BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */ BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_arp, arp_sha) + 4), /* A <- remainder of SHA */ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_arp, arp_sha) + 4), /* A <- remainder of SHA */
BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */ BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */

View File

@@ -32,6 +32,7 @@
#include "dhcp-internal.h" #include "dhcp-internal.h"
#include "fd-util.h" #include "fd-util.h"
#include "socket-util.h" #include "socket-util.h"
#include "unaligned.h"
static int _bind_raw_socket(int ifindex, union sockaddr_union *link, static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
uint32_t xid, const uint8_t *mac_addr, uint32_t xid, const uint8_t *mac_addr,
@@ -70,13 +71,13 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.xid)), /* A <- client identifier */ BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.xid)), /* A <- client identifier */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, xid, 1, 0), /* client identifier == xid ? */ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, xid, 1, 0), /* client identifier == xid ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
BPF_STMT(BPF_LD + BPF_IMM, htobe32(*((unsigned int *) eth_mac))), /* A <- 4 bytes of client's MAC */ BPF_STMT(BPF_LD + BPF_IMM, unaligned_read_be32(&eth_mac->ether_addr_octet[0])), /* A <- 4 bytes of client's MAC */
BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */ BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr)), /* A <- 4 bytes of MAC from dhcp.chaddr */ BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr)), /* A <- 4 bytes of MAC from dhcp.chaddr */
BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */ BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), /* A == 0 ? */ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), /* A == 0 ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
BPF_STMT(BPF_LD + BPF_IMM, htobe16(*((unsigned short *) (((char *) eth_mac) + 4)))), /* A <- remainder of client's MAC */ BPF_STMT(BPF_LD + BPF_IMM, unaligned_read_be16(&eth_mac->ether_addr_octet[4])), /* A <- remainder of client's MAC */
BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */ BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr) + 4), /* A <- remainder of MAC from dhcp.chaddr */ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr) + 4), /* A <- remainder of MAC from dhcp.chaddr */
BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */ BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */